ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
assClozeGapTest.php
Go to the documentation of this file.
1 <?php
2 
20 
29 {
30  protected $backupGlobals = false;
31 
32  protected function setUp(): void
33  {
34  chdir(dirname(__FILE__));
35  chdir('../../../');
36 
37  parent::setUp();
38 
39  require_once './Services/Utilities/classes/class.ilUtil.php';
40  $util_mock = $this->createMock('ilUtil', array('stripSlashes'), array(), '', false);
41  $util_mock->expects($this->any())->method('stripSlashes')->will($this->returnArgument(0));
42  $this->setGlobalVariable('ilUtils', $util_mock);
43  }
44 
46  {
47  // Arrange
48  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
49 
50  // Act
51  $instance = new assClozeGap(0); // 0 - text gap
52 
53  $this->assertInstanceOf('assClozeGap', $instance);
54  }
55 
57  {
58  // Arrange
59  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
60  $instance = new assClozeGap(0); // 0 - text gap
61  $expected = 1; // 1 - select gap
62 
63  // Act
64  $instance->setType($expected);
65  $actual = $instance->getType();
66 
67  // Assert
68  $this->assertEquals($expected, $actual);
69  }
70 
72  {
73  // Arrange
74  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
75  $instance = new assClozeGap(0); // 0 - text gap
76  $expected = 0; // 0 - text gap
77 
78  // Act
79  $instance->setType();
80  $actual = $instance->getType();
81 
82  // Assert
83  $this->assertEquals($expected, $actual);
84  }
85 
87  {
88  // Arrange
89  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
90  $instance = new assClozeGap(0); // 0 - text gap
91  $expected = true;
92 
93  // Act
94  $instance->setShuffle($expected);
95  $actual = $instance->getShuffle();
96 
97  // Assert
98  $this->assertEquals($expected, $actual);
99  }
100 
102  {
103  // Arrange
104  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
105 
106  $instance = new assClozeGap(0); // 0 - text gap
107 
108  // Act
109  $the_unexpected = array('Killing', 'Kunkel', 'Luetzenkirchen',
110  'Meyer', 'Jansen', 'Heyser', 'Becker');
111  $instance->items = $the_unexpected;
112  $instance->setShuffle(true);
113  $theExpected = ['hua', 'haaa', 'some random values'];
114 
115  $transformationMock = $this->getMockBuilder(Transformation::class)->getMock();
116  $transformationMock->expects(self::once())->method('transform')->with($the_unexpected)->willReturn($theExpected);
117  $actual = $instance->getItems($transformationMock);
118 
119  // Assert
120  $this->assertEquals($theExpected, $actual);
121  }
122 
124  {
125  // Arrange
126  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
127  $instance = new assClozeGap(0); // 0 - text gap
128  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
129  $expected = new assAnswerCloze('Esther', 1.0, 0);
130 
131  // Act
132  $instance->addItem($expected);
133  $actual = $instance->getItem(0);
134 
135  // Assert
136  $this->assertEquals($expected, $actual);
137  }
138 
140  {
141  // Arrange
142  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
143  $instance = new assClozeGap(0); // 0 - text gap
144  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
145  $answer = new assAnswerCloze('Bert', 1.0, 0);
146  $expected = new assAnswerCloze('Esther', 1.0, 0);
147 
148  // Act
149  $instance->addItem($answer);
150  $instance->addItem($expected);
151  $actual = $instance->getItem(0);
152 
153  // Assert
154  $this->assertEquals($expected, $actual);
155  }
156 
158  {
159  // Arrange
160  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
161  $instance = new assClozeGap(0); // 0 - text gap
162  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
163  $answer1 = new assAnswerCloze('Bert', 1.0, 0);
164  $answer2 = new assAnswerCloze('Esther', 1.0, 1);
165 
166  $instance->addItem($answer1);
167  $instance->addItem($answer2);
168 
169  $expected = null;
170 
171  // Act
172  $actual = $instance->getItem(2);
173 
174  // Assert
175  $this->assertEquals($expected, $actual);
176  }
177 
179  {
180  // Arrange
181  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
182  $instance = new assClozeGap(0); // 0 - text gap
183 
184  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
185  $answer = new assAnswerCloze('Bert', 1.0, 1);
186  $answer2 = new assAnswerCloze('Fred', 1.0, 2);
187  $answer3 = new assAnswerCloze('Karl', 1.0, 3);
188  $expected = new assAnswerCloze('Esther', 1.0, 0);
189 
190  // Act
191  $instance->addItem($answer);
192  $instance->addItem($answer2);
193  $instance->addItem($answer3);
194  $instance->addItem($expected);
195  $actual = $instance->getItem(0);
196 
197  // Assert
198  $this->assertEquals($expected, $actual);
199  }
200 
201  public function test_getItems_shouldReturnItemsAdded(): void
202  {
203  // Arrange
204  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
205  $instance = new assClozeGap(0); // 0 - text gap
206  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
207  $item1 = new assAnswerCloze('Bert', 1.0, 0);
208  $item2 = new assAnswerCloze('Fred', 1.0, 1);
209  $item3 = new assAnswerCloze('Karl', 1.0, 2);
210  $item4 = new assAnswerCloze('Esther', 1.0, 3);
211  $instance->setShuffle(false);
212  $expected = array($item1, $item2, $item3, $item4);
213  // Act
214  $instance->addItem($item1);
215  $instance->addItem($item2);
216  $instance->addItem($item3);
217  $instance->addItem($item4);
218  $transformationMock = $this->getMockBuilder(Transformation::class)->getMock();
219  $transformationMock->expects(self::never())->method('transform');
220  $actual = $instance->getItems($transformationMock);
221 
222  // Assert
223  $this->assertEquals($expected, $actual);
224  }
225 
227  {
228  // Arrange
229  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
230  $instance = new assClozeGap(0); // 0 - text gap
231  $instance->setShuffle(true);
232  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
233  $expected = [
234  new assAnswerCloze('Bert', 1.0, 0),
235  new assAnswerCloze('Fred', 1.0, 1),
236  new assAnswerCloze('Karl', 1.0, 2),
237  new assAnswerCloze('Esther', 1.0, 3),
238  new assAnswerCloze('Herbert', 1.0, 4),
239  new assAnswerCloze('Karina', 1.0, 5),
240  new assAnswerCloze('Helmut', 1.0, 6),
241  new assAnswerCloze('Kerstin', 1.0, 7),
242  ];
243 
244  $shuffledArray = ['some shuffled array', 'these values dont matter'];
245 
246  // Act
247  foreach ($expected as $item) {
248  $instance->addItem($item);
249  }
250 
251  $transformationMock = $this->getMockBuilder(Transformation::class)->getMock();
252  $transformationMock->expects(self::once())->method('transform')->with($expected)->willReturn($shuffledArray);
253  $actual = $instance->getItems($transformationMock);
254 
255  // Assert
256 
257  $this->assertEquals($shuffledArray, $actual);
258  }
259 
261  {
262  // Arrange
263  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
264  $instance = new assClozeGap(0); // 0 - text gap
265  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
266  $item1 = new assAnswerCloze('Bert', 1.0, 0);
267  $item2 = new assAnswerCloze('Fred', 1.0, 1);
268  $item3 = new assAnswerCloze('Karl', 1.0, 2);
269  $item4 = new assAnswerCloze('Esther', 1.0, 3);
270  $expected = array($item1, $item2, $item3, $item4);
271 
272  // Act
273  $instance->addItem($item1);
274  $instance->addItem($item2);
275  $instance->addItem($item3);
276  $instance->addItem($item4);
277  $actual = $instance->getItemsRaw();
278 
279  // Assert
280  $this->assertEquals($expected, $actual);
281  }
282 
284  {
285  // Arrange
286  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
287  $instance = new assClozeGap(0); // 0 - text gap
288  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
289  $item1 = new assAnswerCloze('Bert', 1.0, 0);
290  $item2 = new assAnswerCloze('Fred', 1.0, 2);
291  $item3 = new assAnswerCloze('Karl', 1.0, 1);
292  $item4 = new assAnswerCloze('Esther', 1.0, 3);
293  $expected = 4;
294 
295  // Act
296  $instance->addItem($item1);
297  $instance->addItem($item2);
298  $instance->addItem($item3);
299  $instance->addItem($item4);
300  $actual = $instance->getItemCount();
301 
302  // Assert
303  $this->assertEquals($expected, $actual);
304  }
305 
306  public function test_setItemPoints_shouldSetItemPoints(): void
307  {
308  // Arrange
309  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
310  $instance = new assClozeGap(0); // 0 - text gap
311  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
312  $item1 = new assAnswerCloze('Esther', 1.0, 0);
313  $instance->addItem($item1);
314  $expected = 4;
315 
316  // Act
317  $instance->setItemPoints(0, $expected);
319  $item_retrieved = $instance->getItem(0);
320  $actual = $item_retrieved->getPoints();
321 
322  // Assert
323  $this->assertEquals($expected, $actual);
324  }
325 
327  {
328  // Arrange
329  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
330  $instance = new assClozeGap(0); // 0 - text gap
331  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
332  $item1 = new assAnswerCloze('Bert', 1.0, 0);
333  $item2 = new assAnswerCloze('Fred', 1.0, 1);
334 
335  $instance->addItem($item1);
336  $instance->addItem($item2);
337 
338  $expected = array('1' => $item2);
339 
340  // Act
341  $instance->deleteItem(0);
342 
343  $actual = $instance->getItemsRaw();
344 
345  // Assert
346  $this->assertEquals($expected, $actual);
347  }
348 
349  public function test_clearItems_shouldClearItems(): void
350  {
351  // Arrange
352  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
353  $instance = new assClozeGap(0); // 0 - text gap
354  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
355  $item1 = new assAnswerCloze('Bert', 1.0, 0);
356  $item2 = new assAnswerCloze('Fred', 1.0, 2);
357  $item3 = new assAnswerCloze('Karl', 1.0, 1);
358  $item4 = new assAnswerCloze('Esther', 1.0, 3);
359 
360  $instance->addItem($item1);
361  $instance->addItem($item2);
362  $instance->addItem($item3);
363  $instance->addItem($item4);
364 
365  $expected = 0;
366 
367  // Act
368  $instance->clearItems();
369  $actual = $instance->getItemCount();
370 
371  // Assert
372  $this->assertEquals($expected, $actual);
373  }
374 
376  {
377  // Arrange
378  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
379  $instance = new assClozeGap(0); // 0 - text gap
380  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
381  $item1 = new assAnswerCloze(20, 1.0, 0);
382 
383  $instance->addItem($item1);
384 
385  $expected = 10;
386 
387  // Act
388  $instance->setItemLowerBound(0, $expected);
389  $item_retrieved = $instance->getItem(0);
390  $actual = $item_retrieved->getLowerBound();
391 
392  // Assert
393  $this->assertEquals($expected, $actual);
394  }
395 
397  {
398  // Arrange
399  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
400  $instance = new assClozeGap(0); // 0 - text gap
401  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
402  $item1 = new assAnswerCloze(20, 1.0, 0);
403 
404  $instance->addItem($item1);
405 
406  $expected = 40;
407 
408  // Act
409  $instance->setItemLowerBound(0, $expected);
410  $item_retrieved = $instance->getItem(0);
411  $actual = $item_retrieved->getLowerBound();
412 
413  // Assert
414  $this->assertNotEquals($expected, $actual);
415  $this->assertEquals($item_retrieved->getAnswerText(), $actual);
416  }
417 
419  {
420  // Arrange
421  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
422  $instance = new assClozeGap(0); // 0 - text gap
423  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
424  $item1 = new assAnswerCloze(5, 1.0, 0);
425 
426  $instance->addItem($item1);
427 
428  $expected = 10;
429 
430  // Act
431  $instance->setItemUpperBound(0, $expected);
432  $item_retrieved = $instance->getItem(0);
433  $actual = $item_retrieved->getUpperBound();
434 
435  // Assert
436  $this->assertEquals($expected, $actual);
437  }
438 
440  {
441  // Arrange
442  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
443  $instance = new assClozeGap(0); // 0 - text gap
444  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
445  $item1 = new assAnswerCloze(20, 1.0, 0);
446 
447  $instance->addItem($item1);
448 
449  $expected = 10;
450 
451  // Act
452  $instance->setItemUpperBound(0, $expected);
453  $item_retrieved = $instance->getItem(0);
454  $actual = $item_retrieved->getUpperBound();
455 
456  // Assert
457  $this->assertNotEquals($expected, $actual);
458  $this->assertEquals($item_retrieved->getAnswerText(), $actual);
459  }
460 
462  {
463  // Arrange
464  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
465  $instance = new assClozeGap(0); // 0 - text gap
466  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
467  $item1 = new assAnswerCloze('Bert', 1.0, 0);
468  $item2 = new assAnswerCloze('Fred', 1.0, 2);
469  $item3 = new assAnswerCloze('Karl', 1.0, 1);
470  $item4 = new assAnswerCloze('Esther', 1.0, 3);
471 
472  $instance->addItem($item1);
473  $instance->addItem($item2);
474  $instance->addItem($item3);
475  $instance->addItem($item4);
476 
477  $expected = strlen($item4->getAnswertext());
478 
479  // Act
480  $actual = $instance->getMaxWidth();
481 
482  // Assert
483  $this->assertEquals($expected, $actual);
484  }
485 
487  {
488  // Arrange
489  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
490  $instance = new assClozeGap(0); // 0 - text gap
491  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
492  $item1 = new assAnswerCloze('Bert', 1.0, 0);
493  $item2 = new assAnswerCloze('Fred', 2.0, 2);
494  $item3 = new assAnswerCloze('Karl', 3.0, 1);
495  $item4 = new assAnswerCloze('Esther', 4.0, 3);
496 
497  $instance->addItem($item1);
498  $instance->addItem($item2);
499  $instance->addItem($item3);
500  $instance->addItem($item4);
501 
502  $expected = array( 0 => 3 );
503 
504  // Act
505  $actual = $instance->getBestSolutionIndexes();
506 
507  // Assert
508  $this->assertEquals($expected, $actual);
509  }
510 
512  {
513  // Arrange
514  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
515  $instance = new assClozeGap(0); // 0 - text gap
516  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
517  $item1 = new assAnswerCloze('Bert', 1.0, 0);
518  $item2 = new assAnswerCloze('Fred', 2.0, 2);
519  $item3 = new assAnswerCloze('Karl', 3.0, 1);
520  $item4 = new assAnswerCloze('Esther', 4.0, 3);
521 
522  // We need the $lng-mock.
523  require_once './Services/Language/classes/class.ilLanguage.php';
524  $lng_mock = $this->createMock('ilLanguage', array('txt'), array(), '', false);
525  $lng_mock->expects($this->any())->method('txt')->will($this->returnValue('Test'));
526  global $DIC;
527  unset($DIC['lng']);
528  $DIC['lng'] = $lng_mock;
529  $GLOBALS['lng'] = $DIC['lng'];
530 
531  $instance->addItem($item1);
532  $instance->addItem($item2);
533  $instance->addItem($item3);
534  $instance->addItem($item4);
535 
536  $expected = 'Esther';
537 
538  // Act
539  $actual = $instance->getBestSolutionOutput($this->getDummyTransformationMock());
540 
541  // Assert
542  $this->assertEquals($expected, $actual);
543  }
544 
546  {
547  // Arrange
548  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
549  $instance = new assClozeGap(0); // 0 - text gap
550  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
551  $item1 = new assAnswerCloze('Bert', 1.0, 0);
552  $item2 = new assAnswerCloze('Fred', 2.0, 2);
553  $item3 = new assAnswerCloze('Karl', 4, 1);
554  $item4 = new assAnswerCloze('Esther', 4, 3);
555 
556  // We need the $lng-mock.
557  require_once './Services/Language/classes/class.ilLanguage.php';
558  $lng_mock = $this->createMock('ilLanguage', array('txt'), array(), '', false);
559  $lng_mock->expects($this->any())->method('txt')->will($this->returnValue('or'));
560  global $DIC;
561  unset($DIC['lng']);
562  $DIC['lng'] = $lng_mock;
563  $GLOBALS['lng'] = $DIC['lng'];
564 
565  $instance->setShuffle(true);
566  $instance->addItem($item1);
567  $instance->addItem($item2);
568  $instance->addItem($item3);
569  $instance->addItem($item4);
570 
571  $expected1 = 'Karl or Esther';
572  $expected2 = 'Esther or Karl';
573 
574  // Act
575  $actual = $instance->getBestSolutionOutput($this->getDummyTransformationMock());
576 
577  // Assert
578  $this->assertTrue(($actual == $expected1) || ($actual == $expected2));
579  }
580 
582  {
583  // Arrange
584  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
585  $instance = new assClozeGap(2); // 0 - text gap
586  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
587  $item1 = new assAnswerCloze(10, 1.0, 0);
588  $item2 = new assAnswerCloze(20, 2.0, 2);
589  $item3 = new assAnswerCloze(30, 3.0, 1);
590  $item4 = new assAnswerCloze(100, 4.0, 3);
591 
592  // We need the $lng-mock.
593  require_once './Services/Language/classes/class.ilLanguage.php';
594  $lng_mock = $this->createMock('ilLanguage', array('txt'), array(), '', false);
595  $lng_mock->expects($this->any())->method('txt')->will($this->returnValue('Test'));
596  global $DIC;
597  unset($DIC['lng']);
598  $DIC['lng'] = $lng_mock;
599  $GLOBALS['lng'] = $DIC['lng'];
600 
601  $instance->addItem($item1);
602  $instance->addItem($item2);
603  $instance->addItem($item3);
604  $instance->addItem($item4);
605 
606  $expected = 100;
607 
608  // Act
609  $actual = $instance->getBestSolutionOutput($this->getDummyTransformationMock());
610 
611  // Assert
612  $this->assertEquals($expected, $actual);
613  }
614 
616  {
617  // Arrange
618  require_once './Modules/TestQuestionPool/classes/class.assClozeGap.php';
619  $instance = new assClozeGap(11); // 0 - text gap
620  require_once './Modules/TestQuestionPool/classes/class.assAnswerCloze.php';
621  $item1 = new assAnswerCloze(10, 1.0, 0);
622  $item2 = new assAnswerCloze(20, 2.0, 2);
623  $item3 = new assAnswerCloze(30, 3.0, 1);
624  $item4 = new assAnswerCloze(100, 4.0, 3);
625 
626  // We need the $lng-mock.
627  require_once './Services/Language/classes/class.ilLanguage.php';
628  $lng_mock = $this->createMock('ilLanguage', array('txt'), array(), '', false);
629  $lng_mock->expects($this->any())->method('txt')->will($this->returnValue('Test'));
630  global $DIC;
631  unset($DIC['lng']);
632  $DIC['lng'] = $lng_mock;
633  $GLOBALS['lng'] = $DIC['lng'];
634 
635  $instance->addItem($item1);
636  $instance->addItem($item2);
637  $instance->addItem($item3);
638  $instance->addItem($item4);
639 
640  $expected = '';
641 
642  // Act
643  $actual = $instance->getBestSolutionOutput($this->getDummyTransformationMock());
644 
645  // Assert
646  $this->assertEquals($expected, $actual);
647  }
648 
650  {
651  $transformationMock = $this->getMockBuilder(Transformation::class)->getMock();
652  $transformationMock->expects(self::any())->method('transform')->willReturnCallback(static function (array $array) {
653  return $array;
654  });
655 
656  return $transformationMock;
657  }
658 }
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
test_addGetItem_shouldReturnValueUnchanged()
test_getItemsWithShuffle_shouldReturnItemsAddedShuffled()
test_getMaxWidth_shouldReturnCharacterCountOfLongestAnswertext()
test_getBestSolutionOutput_shouldReturnBestSolutionOutput_CaseNumeric()
test_getBestSolutionOutput_shouldReturnBestSolutionOutput_CaseTextMulti()
test_instantiateObject_shouldReturnInstance()
Class assBaseTestCase.
test_setType_shouldSetDefaultIfNotPassed()
Class for cloze question gaps.
test_getItemsRaw_shouldReturnItemsAdded()
test_addGetItem_shouldReturnValueUnchangedMultiplePlus()
global $DIC
Definition: feed.php:28
test_setItemUpperBound_shouldSetItemsAnswerIfBoundTooLow()
test_deleteItem_shouldDeleteGivenItem()
test_setItemLowerBound_shouldSetItemsLowerBound()
test_getItemCount_shouldReturnCorrectCount()
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
test_getBestSolutionIndexes_shouldReturnBestSolutionIndexes()
test_setItemUpperBound_shouldSetItemsUpperBound()
test_arrayShuffle_shouldNotReturnArrayUnshuffled()
test_getBestSolutionOutput_shouldReturnBestSolutionOutput_CaseText()
test_getItem_shouldReturnNullIfNoItemAtGivenIndex()
test_getItems_shouldReturnItemsAdded()
test_getBestSolutionOutput_shouldReturnEmptyStringOnUnknownType_WhichMakesNoSenseButK()
A transformation is a function from one datatype to another.
setGlobalVariable(string $name, $value)
test_addGetItem_shouldReturnValueUnchangedMultiple()
test_setItemLowerBound_shouldSetItemsAnswerIfBoundTooHigh()
test_setGetType_shouldReturnUnchangedValue()
test_setGetShuffle_shouldReturnUnchangedValue()