You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+32-13Lines changed: 32 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -37,16 +37,17 @@ The design of this example differs in two significant ways from the traditional
37
37
Steps to understanding the system
38
38
---------------------------------
39
39
40
-
**Play with the running application.**
40
+
**Run the application.**
41
41
42
42
Begin by downloading the code, invoking "play run" in your shell, then retrieving http://localhost:9000
43
-
to retrieve the single form as illustrated at the top of this page. The form displays the fields
43
+
to display the single form illustrated at the top of this page. The form displays the fields
44
44
associated with a "Student": Name, Password, Hobbies, Level, GPA, and Majors. Some of these
45
-
are required, some are optional. Try filling out the form in both valid and invalid ways.
46
-
45
+
are required, some are optional. Try filling out the form in both valid and invalid ways and
46
+
pressing Submit to see what happens.
47
47
48
48
When you submit a valid version of the form, the system will redisplay the form with exactly the
49
-
same data that you entered.
49
+
same data that you entered, and also show a representation of the Student model instance
50
+
created from the form values.
50
51
51
52
**Run the tests.**
52
53
@@ -71,7 +72,7 @@ to invoke the test cases. You should get output similar to the following:
71
72
72
73
We'll come back to this later, but this step verifies that tests run correctly in your environment.
73
74
74
-
**Review the controller.**
75
+
**Review the controllers.**
75
76
76
77
Now review the controller class. [Application](https://github.com/ics-software-engineering/play-example-form/blob/master/app/controllers/Application.java)
77
78
has just two methods: getIndex() which displays the form in the index page and postIndex() that processes a form submission
@@ -111,11 +112,7 @@ is where things get most interesting. The [main](https://github.com/ics-softwa
111
112
and [index](https://github.com/ics-software-engineering/play-example-form/blob/master/app/views/index.scala.html)
112
113
templates are pretty much what you'd expect.
113
114
114
-
Note that the main template imports JQuery which is needed for Bootstrap Javascript components and not normally shown
115
-
in the built-in Play examples. What is really not shown in the built-in Play examples is the
116
-
fact that in order to test your code with HTMLUnit, you cannot use a version of JQuery more recent than 1.8.3.
117
-
Look at [Build.scala](https://github.com/ics-software-engineering/play-example-form/blob/master/project/Build.scala#L17-19)
118
-
to see how to load a newer version of Bootstrap with an older, HTMLUnit-compliant version of JQuery.
115
+
Note that the main template shows how to import JQuery in case you want to use Bootstrap Javascript components.
119
116
120
117
The second thing to review is the [views.bootstrap](https://github.com/ics-software-engineering/play-example-form/tree/master/app/views/bootstrap)
121
118
subpackage, containing Bootstrap 2.x Scala templates for various form controls. Kudos to [Jason
@@ -125,20 +122,42 @@ Finally, the [views.formdata](https://github.com/ics-software-engineering/play-e
125
122
subpackage contains the single backing class ([StudentFormData](https://github.com/ics-software-engineering/play-example-form/blob/master/app/views/formdata/StudentFormData.java)) required for this application.
126
123
Note that the backing class consists of public fields containing the String data to be displayed/bound in the form,
127
124
as well as a validate() method that determines if the submitted form data is valid or not.
125
+
126
+
**Review the tests.**
127
+
128
+
Testing is pretty straightforward, uses [Fluentlenium](https://github.com/FluentLenium/FluentLenium#what-is-fluentlenium-), and implements the
Start by looking at [IndexPage](https://github.com/ics-software-engineering/play-example-form/blob/master/test/tests/pages/IndexPage.java).
132
+
This class implements a bunch of methods to fill out the form and check to see whether the
133
+
displayed form contains a success or error message. Note that most of these methods depend upon
134
+
finding an HTML element with a specific ID, and so the Bootstrap Scala templates need to make
135
+
sure these ID fields are set correctly.
136
+
137
+
The actual test code is in [ViewTest](https://github.com/ics-software-engineering/play-example-form/blob/master/test/tests/ViewTest.java).
138
+
There are four tests: one that just checks that we can retrieve the page, one that tests that
139
+
submitting an empty form generates a validation error, one that submits a form filled out
140
+
from a valid Student ID, and a final one that fills out a valid form manually by using the
141
+
IndexPage methods.
142
+
143
+
Getting tests to work exposes an unfortunate library versioning issue: HTMLUnit requires
144
+
a version of JQuery no later than 1.8.3, while recent versions of Twitter Bootstrap
145
+
have a Maven dependency of JQuery 1.9.0. [Build.scala](https://github.com/ics-software-engineering/play-example-form/blob/master/project/Build.scala#L17-19)
146
+
illustrates how to load a newer version of Bootstrap with an older, HTMLUnit-compliant version of JQuery.
128
147
129
148
Issues
130
149
------
131
150
132
151
While this code works and is pretty easy to understand, there are at least two design problems with it
133
152
that I can see:
134
153
135
-
* Verbosity. It's kind of a drag to have two representations for a Student, one as a model and
154
+
***Verbosity.** It's kind of a drag to have two representations for a Student, one as a model and
136
155
one as a backing class for forms. I know that I presented this as a feature, but at the end
137
156
of the day it's born of necessity. Perhaps there exists an elegant way to implement composite entities
138
157
(i.e. a Student that contains a List of Hobbies) in which display, binding, and validation
139
158
can be done easily and understandably with a single class.
140
159
141
-
* Integrity. The current code encapsulates validation in the StudentFormData class, and certain
160
+
***Integrity.** The code provides validation in the StudentFormData class, and certain
142
161
methods (such as Student.makeInstance) must assume that they are being passed a valid
143
162
StudentFormData instance. That kind of assumption is worrisome, and annotation-based
144
163
constraints could avoid it. Annotation-based constraints also offer the potential
0 commit comments