}
// this case is especially interesting because the numeric array keys are always
// converted to integers by array
// furthermore, (int)0 == (string)'w1' succeeds
$w = new sfWidgetFormSchema(array('w1' => $w1, '0' => $w2));
$w->moveField(0, sfWidgetFormSchema::FIRST);
$t->is($w->getPositions(), array('0', 'w1'), '->moveField() compares field names as strings');
$w = new sfWidgetFormSchema(array('w1' => $w1, '0' => $w2));
$w->moveField('0', sfWidgetFormSchema::FIRST);
$t->is($w->getPositions(), array('0', 'w1'), '->moveField() compares field names as strings');
$w = new sfWidgetFormSchema(array('w1' => $w1, 'w2' => $w2, '0' => $w1));
$w->moveField('w1', sfWidgetFormSchema::BEFORE, '0');
$t->is($w->getPositions(), array('w2', 'w1', '0'), '->moveField() compares field names as strings');
$w = new sfWidgetFormSchema(array('w1' => $w1, 'w2' => $w2, '0' => $w1));
$w->moveField('w1', sfWidgetFormSchema::BEFORE, 0);
$t->is($w->getPositions(), array('w2', 'w1', '0'), '->moveField() compares field names as strings');
// ->getGlobalErrors()
$t->diag('->getGlobalErrors()');
$w = new sfWidgetFormSchema();
$w['w1'] = $w1;
$w['w2'] = new sfWidgetFormInputHidden();
$w['w3'] = new sfWidgetFormSchema();
$w['w3']['w1'] = $w1;
$w['w3']['w2'] = new sfWidgetFormInputHidden();
$errors = array('global error', 'w1' => 'error for w1', 'w2' => 'error for w2', 'w4' => array('w1' => 'error for w4/w1', 'w2' => 'error for w4/w2', 'w3' => 'error for w4/w3'), 'w4' => 'error for w4');
$t->is($w->getGlobalErrors($errors), array('global error', 'error for w4', 'W2' => 'error for w2'), '->getGlobalErrors() returns an array of global errors, errors for hidden fields, and errors for non existent fields');
// ->render()
$t->diag('->render()');
$w = new sfWidgetFormSchema();
try {
    $w->render(null, 'string');
}
try {
    $w->setPositions(array('w1'));
    $t->fail('->setPositions() throws an InvalidArgumentException if you miss a field name');
} catch (InvalidArgumentException $e) {
    $t->pass('->setPositions() throws an InvalidArgumentException if you miss a field name');
}
// ->moveField()
$t->diag('->moveField()');
$w = new sfWidgetFormSchema();
$w['w1'] = $w1;
$w['w2'] = $w2;
$w['w3'] = $w1;
$w['w4'] = $w2;
$w->moveField('w1', sfWidgetFormSchema::BEFORE, 'w3');
$t->is($w->getPositions(), array('w2', 'w1', 'w3', 'w4'), '->moveField() can move a field before another one');
$w->moveField('w1', sfWidgetFormSchema::LAST);
$t->is($w->getPositions(), array('w2', 'w3', 'w4', 'w1'), '->moveField() can move a field to the end');
$w->moveField('w1', sfWidgetFormSchema::FIRST);
$t->is($w->getPositions(), array('w1', 'w2', 'w3', 'w4'), '->moveField() can move a field to the beginning');
$w->moveField('w1', sfWidgetFormSchema::AFTER, 'w3');
$t->is($w->getPositions(), array('w2', 'w3', 'w1', 'w4'), '->moveField() can move a field before another one');
try {
    $w->moveField('w1', sfWidgetFormSchema::AFTER);
    $t->fail('->moveField() throws an LogicException if you don\'t pass a relative field name with AFTER');
} catch (LogicException $e) {
    $t->pass('->moveField() throws an LogicException if you don\'t pass a relative field name with AFTER');
}
try {
    $w->moveField('w1', sfWidgetFormSchema::BEFORE);
    $t->fail('->moveField() throws an LogicException if you don\'t pass a relative field name with BEFORE');