1 | package dbnp.studycapturing |
---|
2 | |
---|
3 | import grails.test.* |
---|
4 | import dbnp.data.Ontology |
---|
5 | |
---|
6 | class TemplateFieldTests extends GrailsUnitTestCase { |
---|
7 | def testEvent; |
---|
8 | protected void setUp() { |
---|
9 | super.setUp() |
---|
10 | |
---|
11 | // Create the template itself |
---|
12 | def testTemplate = new Template( |
---|
13 | name: 'Template for testing relative date fields', |
---|
14 | entity: dbnp.studycapturing.Event, |
---|
15 | fields: [ |
---|
16 | new TemplateField( |
---|
17 | name: 'testStartDate', |
---|
18 | type: TemplateFieldType.DATE |
---|
19 | ), |
---|
20 | new TemplateField( |
---|
21 | name: 'testRelTime', |
---|
22 | type: TemplateFieldType.RELTIME |
---|
23 | ), |
---|
24 | new TemplateField( |
---|
25 | name: 'testFile', |
---|
26 | type: TemplateFieldType.FILE |
---|
27 | ) |
---|
28 | ] |
---|
29 | ); |
---|
30 | |
---|
31 | // Add static methods to Template |
---|
32 | mockDomain( Template, [testTemplate] ); |
---|
33 | mockDomain( TemplateField, testTemplate.fields ); |
---|
34 | |
---|
35 | this.testEvent = new Event( |
---|
36 | template: testTemplate, |
---|
37 | startTime: 3600, |
---|
38 | endTime: 7200 |
---|
39 | ); |
---|
40 | |
---|
41 | mockDomain( Event, [testEvent] ); |
---|
42 | this.testEvent.save(); |
---|
43 | } |
---|
44 | |
---|
45 | protected void tearDown() { |
---|
46 | super.tearDown() |
---|
47 | } |
---|
48 | |
---|
49 | void testInUse() { |
---|
50 | |
---|
51 | // All template fields in the testTemplate are in use (even in use on a object) |
---|
52 | assert testEvent.template.fields.size() == 3; |
---|
53 | testEvent.template.fields.each { |
---|
54 | if( it != null ) { |
---|
55 | assert it.inUse(); |
---|
56 | } |
---|
57 | } |
---|
58 | |
---|
59 | // Create 2 template fields and use the first in a template, the second is not used |
---|
60 | TemplateField t1 = new TemplateField( |
---|
61 | name: 'test1', |
---|
62 | type: TemplateFieldType.DATE, |
---|
63 | entity: dbnp.studycapturing.Event |
---|
64 | ).save(); |
---|
65 | TemplateField t2 = new TemplateField( |
---|
66 | name: 'test2', |
---|
67 | type: TemplateFieldType.DATE, |
---|
68 | entity: dbnp.studycapturing.Event |
---|
69 | ).save(); |
---|
70 | |
---|
71 | mockDomain( TemplateField, [t1, t2] ); |
---|
72 | |
---|
73 | def template1 = new Template( |
---|
74 | name: 'Template for testing inUse', |
---|
75 | entity: dbnp.studycapturing.Event, |
---|
76 | fields: [ |
---|
77 | t1 |
---|
78 | ] |
---|
79 | ).save(); |
---|
80 | |
---|
81 | assert t1.inUse(); |
---|
82 | assert !t2.inUse(); |
---|
83 | |
---|
84 | } |
---|
85 | |
---|
86 | void testRelTimeFieldCreation() { |
---|
87 | def RelTimeField = new TemplateField( |
---|
88 | name: 'RelTime', |
---|
89 | type: TemplateFieldType.RELTIME |
---|
90 | ); |
---|
91 | } |
---|
92 | |
---|
93 | void testRelTimeSetValue() { |
---|
94 | // Check whether the field exists |
---|
95 | assert this.testEvent.fieldExists( 'testRelTime' ); |
---|
96 | |
---|
97 | // See that it is not a domain field |
---|
98 | assert !this.testEvent.isDomainField( 'testRelTime' ); |
---|
99 | println( this.testEvent.getStore( TemplateFieldType.RELTIME ) ); |
---|
100 | |
---|
101 | this.testEvent.setFieldValue( 'testRelTime', 10 ); |
---|
102 | assert this.testEvent.getFieldValue( 'testRelTime' ) == 10; |
---|
103 | |
---|
104 | this.testEvent.setFieldValue( 'testRelTime', 0 ); |
---|
105 | assert this.testEvent.getFieldValue( 'testRelTime' ) == 0; |
---|
106 | |
---|
107 | this.testEvent.setFieldValue( 'testRelTime', -130 ); |
---|
108 | assert this.testEvent.getFieldValue( 'testRelTime' ) == -130; |
---|
109 | |
---|
110 | // RelTime must be able to handle 100 years |
---|
111 | long hundredYears = 100L * 365 * 24 * 3600; |
---|
112 | this.testEvent.setFieldValue( 'testRelTime', hundredYears ); |
---|
113 | assert this.testEvent.getFieldValue( 'testRelTime' ) == hundredYears; |
---|
114 | } |
---|
115 | |
---|
116 | // Tests the parsing of a string for relative dates |
---|
117 | // @see TemplateEntity.setFieldValue |
---|
118 | // |
---|
119 | // The relative date may be set as a string, using the following format |
---|
120 | // |
---|
121 | // #w #d #h #m #s |
---|
122 | // |
---|
123 | // Where w = weeks, d = days, h = hours, m = minutes, s = seconds |
---|
124 | // |
---|
125 | // The spaces between the values are optional. Every timespan |
---|
126 | // (w, d, h, m, s) must appear at most once. You can also omit |
---|
127 | // timespans if needed or use a different order. |
---|
128 | // Other characters are disregarded, allthough results may not |
---|
129 | // always be as expected. |
---|
130 | // |
---|
131 | // If an incorrect format is used, which can't be parsed |
---|
132 | // an IllegalFormatException is thrown. |
---|
133 | // |
---|
134 | // An empty span is treated as zero seconds. |
---|
135 | // |
---|
136 | // Examples: |
---|
137 | // --------- |
---|
138 | // 5d 3h 20m // 5 days, 3 hours and 20 minutes |
---|
139 | // 6h 2d // 2 days, 6 hours |
---|
140 | // 10m 200s // 13 minutes, 20 seconds (200s == 3m + 20s) |
---|
141 | // 5w4h15m // 5 weeks, 4 hours, 15 minutes |
---|
142 | // |
---|
143 | // 16x14w10d // Incorrect. 16x is disregarded, so the |
---|
144 | // // result is 15 weeks, 3 days |
---|
145 | // 13days // Incorrect: days should be d, but this is |
---|
146 | // // parsed as 13d, 0 seconds |
---|
147 | // |
---|
148 | void testRelTimeParser() { |
---|
149 | def s = 1L; |
---|
150 | def m = 60L * s; |
---|
151 | def h = 60L * m; |
---|
152 | def d = 24L * h; |
---|
153 | def w = 7L * d; |
---|
154 | |
---|
155 | this.testEvent.setFieldValue( 'testRelTime', '' ); |
---|
156 | assert this.testEvent.getFieldValue( 'testRelTime' ) == 0; |
---|
157 | |
---|
158 | this.testEvent.setFieldValue( 'testRelTime', ' ' ); |
---|
159 | assert this.testEvent.getFieldValue( 'testRelTime' ) == 0; |
---|
160 | |
---|
161 | this.testEvent.setFieldValue( 'testRelTime', '5d 3h 20m' ); |
---|
162 | assert this.testEvent.getFieldValue( 'testRelTime' ) == 5 * d + 3 * h + 20 * m; |
---|
163 | |
---|
164 | this.testEvent.setFieldValue( 'testRelTime', '6h 2d' ); |
---|
165 | assert this.testEvent.getFieldValue( 'testRelTime' ) == 2 * d + 6 * h; |
---|
166 | |
---|
167 | this.testEvent.setFieldValue( 'testRelTime', '10m 200s' ); |
---|
168 | assert this.testEvent.getFieldValue( 'testRelTime' ) == 10 * m + 200 * s; |
---|
169 | |
---|
170 | this.testEvent.setFieldValue( 'testRelTime', '5w4h15m' ); |
---|
171 | assert this.testEvent.getFieldValue( 'testRelTime' ) == 5 * w + 4 * h + 15 * m; |
---|
172 | |
---|
173 | // Should parse correctly, allthough it is not completely correct |
---|
174 | this.testEvent.setFieldValue( 'testRelTime', '16x14w10d' ); |
---|
175 | assert this.testEvent.getFieldValue( 'testRelTime' ) == 14 * w + 10 * d; |
---|
176 | |
---|
177 | this.testEvent.setFieldValue( 'testRelTime', '13days' ); |
---|
178 | assert this.testEvent.getFieldValue( 'testRelTime' ) == 13 * d; |
---|
179 | |
---|
180 | // Test whether an IllegalFormatException is thrown |
---|
181 | try { |
---|
182 | this.testEvent.setFieldValue( 'testRelTime', 'nonexistent relative date' ); |
---|
183 | fail(); |
---|
184 | } catch(IllegalArgumentException ex) { |
---|
185 | } catch( Exception ex ) { |
---|
186 | fail(); |
---|
187 | } |
---|
188 | } |
---|
189 | |
---|
190 | void testContentEquals() { |
---|
191 | // Check whether the fields matter |
---|
192 | TemplateField tf1 = new TemplateField( entity: dbnp.studycapturing.Subject, name: 'Weight', type: TemplateFieldType.LONG, unit: 'kg', comments: 'Weight field' ) |
---|
193 | TemplateField tf2 = new TemplateField( entity: dbnp.studycapturing.Subject, name: 'Weight', type: TemplateFieldType.LONG, unit: 'kg', comments: 'Weight field 2' ) |
---|
194 | TemplateField tf3 = new TemplateField( entity: dbnp.studycapturing.Subject, name: 'Length', type: TemplateFieldType.LONG, unit: 'm', comments: 'Length field' ) |
---|
195 | TemplateField tf4 = new TemplateField( entity: dbnp.studycapturing.Subject, name: 'Length', type: TemplateFieldType.LONG, unit: 'm', comments: 'Length field', required: true ) |
---|
196 | TemplateField tf5 = new TemplateField( entity: dbnp.studycapturing.Study, name: 'Length', type: TemplateFieldType.LONG, unit: 'm', comments: 'Length field', required: true ) |
---|
197 | |
---|
198 | TemplateField tf6 = new TemplateField( entity: dbnp.studycapturing.Subject, name: 'Species', type: TemplateFieldType.ONTOLOGYTERM ) |
---|
199 | TemplateField tf7 = new TemplateField( entity: dbnp.studycapturing.Subject, name: 'Species', type: TemplateFieldType.ONTOLOGYTERM ) |
---|
200 | |
---|
201 | TemplateField tf8 = new TemplateField( entity: dbnp.studycapturing.Subject, name: 'Species', type: TemplateFieldType.STRINGLIST ) |
---|
202 | TemplateField tf9 = new TemplateField( entity: dbnp.studycapturing.Subject, name: 'Species', type: TemplateFieldType.STRINGLIST ) |
---|
203 | |
---|
204 | mockDomain( TemplateField, [tf1, tf2, tf3, tf4, tf5, tf6, tf7, tf8, tf9] ); |
---|
205 | |
---|
206 | assert( tf1.contentEquals( tf1 ) ); |
---|
207 | assert( tf1.contentEquals( tf2 ) ); |
---|
208 | assert( tf2.contentEquals( tf1 ) ); |
---|
209 | assert( !tf1.contentEquals( tf3 ) ); |
---|
210 | assert( !tf3.contentEquals( tf4 ) ); |
---|
211 | assert( !tf5.contentEquals( tf4 ) ); |
---|
212 | |
---|
213 | // Test ontology fields |
---|
214 | Ontology o1 = new Ontology( ncboId: 1000, ncboVersionedId: 14192, name: "Ontology 1" ) |
---|
215 | Ontology o2 = new Ontology( ncboId: 1000, ncboVersionedId: 14192, name: "Ontology 2" ) |
---|
216 | Ontology o3 = new Ontology( ncboId: 1000, ncboVersionedId: 5123, name: "Ontology 3" ) |
---|
217 | Ontology o4 = new Ontology( ncboId: 4123, ncboVersionedId: 14192, name: "Ontology 4" ) |
---|
218 | |
---|
219 | tf6.addToOntologies( o1 ) |
---|
220 | |
---|
221 | // Different number of ontologies |
---|
222 | assert( !tf6.contentEquals( tf7 ) ); |
---|
223 | |
---|
224 | tf7.addToOntologies( o1 ); |
---|
225 | |
---|
226 | // Same ontologies |
---|
227 | assert( tf6.contentEquals( tf7 ) ); |
---|
228 | |
---|
229 | tf7.ontologies.clear() |
---|
230 | tf7.addToOntologies( o2 ); |
---|
231 | |
---|
232 | // Ontologies with the same ncboId |
---|
233 | assert( !tf6.contentEquals( tf7 ) ); |
---|
234 | |
---|
235 | tf6.ontologies.clear(); tf7.ontologies.clear() |
---|
236 | tf6.addToOntologies( o1 ) |
---|
237 | tf6.addToOntologies( o4 ) |
---|
238 | tf7.addToOntologies( o4 ); |
---|
239 | tf7.addToOntologies( o1 ); |
---|
240 | |
---|
241 | // Different order but same ontologies |
---|
242 | assert( tf6.contentEquals( tf7 ) ); |
---|
243 | |
---|
244 | // Test listentries |
---|
245 | |
---|
246 | assert( tf8.contentEquals( tf9 ) ); |
---|
247 | |
---|
248 | TemplateFieldListItem l1 = new TemplateFieldListItem( name: 'string1' ); |
---|
249 | TemplateFieldListItem l2 = new TemplateFieldListItem( name: 'string1' ); |
---|
250 | TemplateFieldListItem l3 = new TemplateFieldListItem( name: 'string2' ); |
---|
251 | TemplateFieldListItem l4 = new TemplateFieldListItem( name: 'string3' ); |
---|
252 | |
---|
253 | tf8.addToListEntries( l1 ); |
---|
254 | |
---|
255 | // Different number of list entries |
---|
256 | assert( !tf8.contentEquals( tf9 ) ); |
---|
257 | |
---|
258 | tf9.addToListEntries( l1 ); |
---|
259 | |
---|
260 | // Same list entries |
---|
261 | assert( tf8.contentEquals( tf9 ) ); |
---|
262 | |
---|
263 | tf9.listEntries.clear(); |
---|
264 | tf9.addToListEntries( l2 ); |
---|
265 | |
---|
266 | // Different list entries with the same name |
---|
267 | assert( tf8.contentEquals( tf9 ) ); |
---|
268 | |
---|
269 | tf9.listEntries.clear(); |
---|
270 | tf9.addToListEntries( l3 ); |
---|
271 | |
---|
272 | // Different list entries |
---|
273 | assert( !tf8.contentEquals( tf9 ) ); |
---|
274 | |
---|
275 | // Same entries but different order |
---|
276 | tf8.listEntries.clear(); |
---|
277 | tf9.listEntries.clear(); |
---|
278 | tf8.addToListEntries( l2 ); |
---|
279 | tf8.addToListEntries( l3 ); |
---|
280 | tf9.addToListEntries( l3 ); |
---|
281 | tf9.addToListEntries( l2 ); |
---|
282 | |
---|
283 | // Different order but same list entries |
---|
284 | assert( tf8.contentEquals( tf9 ) ); |
---|
285 | |
---|
286 | } |
---|
287 | } |
---|