-
Notifications
You must be signed in to change notification settings - Fork 47
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
Add more documentation to EventStream ? #34
Comments
Here are my ideas for better documentation:
/*
ConditionOn Explanation:
EventStream<X> A
EventStream<X> B = A.conditionOn(Property)
*/
// Returns B. When A emits an event, B also emits that event if Property evaluates to true.
// The property is analogous to creating a gate that is either open (evaluates to true)
// or closed (evaluates to false).
/*
Combine Explanation
EventStream<A> 1
EventStream<B> 2
EventStream<C> 3
. . .
EventStream<?> N
EventStream<Tuple#<A, B, C, ..., ?> X = EventStreams.combine(1, 2, 3, ..., N)
*/
// Returns X. X does not emit its combined event until 1, 2, 3, ..., and N have all emitted at least one event.
// Once X emits its first event, it will emit a new event every time 1, 2, 3, ..., or N emit a new event.
|
I've written some pages for the wiki that should help guide someone who is unfamiliar with this library. |
Great, many thanks for volunteering to do this! |
Somewhere I would like to have the advice to minimize the number of calls that return a |
I want to write another page that focuses on composing EventStreams, so it'd probably be best if that content went into that page. |
I wrote another page that includes the Subscription minimizing. Beyond that, there's the EventStream ecosystem. I think a good way to show the relationships between categories would be to map the library using Freeplane and screenshotting it. |
I've uploaded a photo in the wiki that shows the idea I had. I'm sure that photo could be refined by better categorizing the methods from EventStream. However, that's where my knowledge of this library starts to get fuzzy pretty fast. Additionally, I forgot to add |
Thanks! Regarding your composition example, you split EventStream<Paint> fillChanger = combo.map(t -> t.map((hover, ctrl, shift, transfer) -> {
if(!hover && !ctrl && !shift && !transfer) return Color.RED;
else if(...) ...;
...
else ...;
})); You also seem to be covering only 6 cases out of 16 possible. Having to merge |
Lol... Yeah, I figured my approach wasn't very efficient. :-) My goal was just to make sure people got the idea of starting from the final EventStream and then working backwards.
You mean the other methods in the
Aye... But that's the workaround I came up with in my program's code.
Aye, those would be. |
No. You have 4 boolean variables. That gives 24=16 combinations. What color corresponds to, e.g., YNNY? |
Ah... I was just trying to come up with a simple example that uses multiple inputs. I also didn't want to have to create a table that showed all 16 combinations, just enough to get the point across. |
Doesn't the current version mean that for the undefined combinations, the color depends on the previous state, and thus is not unique? You don't necessarily have to list all 16 rows. A row
covers 8 cases and translates to an |
Yes.
I think I understand what you're staying, but not entirely. |
All I'm saying is that these 8 rows
that would directly translate to 8 if(!a && !b && !c && !d) return RED;
else if(!a && !b && !c && d) return RED;
else if(!a && !b && c && !d) return RED;
...
else if(!a && b && c && d) return RED; can be captured as
which translates to if(!a) return RED; |
So, I think I finally have the words to rephrase what you're saying here :-D (I didn't understand you well enough the first night I read this to be able to restate what you said, but looking at it now, I believe I can). The mapping example I gave in the wiki page allows for 16 total combinations. However, my example only addresses 6 of those possible combinations. Thus, there are 10 situations where an Event is emitted, but no code is run. So, if I'm understanding you correctly, yes you are right. I could and probably should have done that for neater code. |
Getting back to this topic...
On a different note, I've been reading through the book, Java Testing with Spock, because I've heard about tests before but now I actually understand why they're worth writing. So, would the tests themselves also be included in the scope of this issue? And if so, what about using Spock instead of JUnit? |
What do you mean by
Do you mean writing more tests, or referring to tests as documentation? I'm not familiar with Spock. What benefits would it bring? |
I mean should the tests be updated to include more comments throughout the test itself? Most of the tests that have been written only have code and not comments explaining what is expected at various parts throughout the test or what each object within the test does. This is part of the reason why I'm also bringing up Spock. Whereas a JUnit test is shown as @Test
void someTest() {
// set up code
// some other code
// more set up code
// does anyone really know what's going on here????
// ...
// oh look! Some "assertEquals" statements
} a Spock test would look like: def "when user presses shift, Rectangle's fill color will change to Red"() {
// this is the set up part of the code
given: "a rectangle"
Rectangle rectangle = new Rectangle()
and: "a property that restricts changes when false"
Var<Boolean> allowChange = Var.simpleVar(true)
and: "an EventStream that emits an event when shift is pressed & allowChange is true"
EventStream<KeyEvent> keyPressed = EventStreams
.eventsOf(rectangle, KeyEvent.KEY_PRESSED)
.filter(it.code == KeyCode.SHIFT)
.conditionOn(allowChange)
and: "a subscriber to keyPressed that changes rectangle's fill color"
keyPressed.subscribe( { rectangle.setFill(Color.RED) })
and: "a fake KeyEvent"
KeyEvent event = Stub(KeyEvent)
event.getTarget() >> rectangle
event.isShiftDown() >> true
// this is the trigger or test case
when: "the user presses shift"
Event.fireEvent(event)
// this evaluates whether the test passes or fails
then: "the rectangle's fill changes to Red"
rectangle.fillProperty().get() == Color.RED
} Spock brings the following features:
For example, parameterized tests look like: def "some parameterized test"() {
given: "A rectangle with a starting color and layoutY value"
Rectangle rectangle = new Rectangle()
rectangle.setFill(color)
rectangle.setLayoutY(position)
when: "randomize is called"
// let's say randomize increments position by 2 and
// changes the fill color to the next color in the rainbow
then: "Rectangle has the correct color and layoutY value"
rectangle.getFill() == newColor
rectangle.getLayoutY() == newPosition
where: "inputs and outputs are"
// normally, this table would line up vertically properly,
// but that's hard to do on here.
color | position || newColor | newPosition
Color.RED | 0 || Color.ORANGE | 2
Color.YELLOW | 2 || Color.GREEN | 4
// etc. |
I see. If there's a reasonable Java version, I'm not opposed to adding Spock as a test framework. Though not instead of JUnit, but alongside it. |
It uses groovy, so I'm guessing that's a no ;-) To use it, one would need to add a dependency to the groovy language. |
The dependency would only be for tests, not for the production release, so I don't mind that. But I don't think I want to drag another language into RichTextFX. I wouldn't mind using some other BDD framework that works in pure Java. Though I don't have experience with or recommendation for any. |
Well... I think the framework is helpful for various things, but that doesn't mean it needs to be used here. I was thinking more in terms of clarity: if we want to make the tests more understandable, then Spock would do a good job at that, but the same purpose could be achieved if the JUnit tests already written are updated with more commentary. |
What functionality doesn't exist in JUnit that you would want to use here? |
It's a double-edged sword, since you limit the audience/writers to people willing to read/write Groovy.
The question is, is there a pure Java testing framework that has the functionality similar to Spock's, that you would like to use? |
Good point.
No, JUnit is fine. My goal here is just to make the tests clearer. That can be done easily with some commentary. I just thought I'd mention Spock because I think it does this more clearly than JUnit. |
I just noticed that you moved the 'Error Handling' part in the home page's wiki to Obsolete. With that being so, what does a developer use to debug an EventStream? I've understood the |
Yes, |
I've updated the EventStream Intro page to include a small section about debugging with hook at its end. |
👍 |
I added a page on State Machines to the wiki as your blog post is not something most people will see unless they know where to look and the class itself might get lost among all the other classes. This makes it much easier to find and see its usages. |
Thanks for putting some effort into documentation! 👍 |
The only thing left to do in this issue is document the |
I wanted to add more documentation to
EventStream
that explains a few things:EventStream
object: creation, subscribe, unsubscribeSubscription
and how and why to use it to prevent memory leaksEventStream
objectWhen I first looked at this library, the Readme file helped show the usefulness of
EventStream
objects in general. SinceEventStream
, as opposed toVal
/Var
orLiveList
, was demonstrated in the Readme file, I looked at that first. However, I didn't immediately know where to go from there, much less how to use the code in my program. My guess is that others who wish to know more about how to use this library would follow a similar path, hence why I think the documentation should be added toEventStream
.The text was updated successfully, but these errors were encountered: