$ws = new sfWidgetFormSchema();
$ws->addFormFormatter('stub', new FormFormatterStub());
$ws->setFormFormatterName('stub');
$w = new sfWidgetFormSelect(array('choices' => array('foo' => 'bar', 'foobar' => 'foo')));
$w->setParent($ws);
$dom->loadHTML($w->render('foo'));
$css = new sfDomCssSelector($dom);
$t->is($css->matchSingle('#foo option[value="foo"]')->getValue(), 'translation[bar]', '->render() translates the options');
$t->is($css->matchSingle('#foo option[value="foobar"]')->getValue(), 'translation[foo]', '->render() translates the options');
// optgroup support with translated choices
$t->diag('optgroup support with translated choices');
$ws = new sfWidgetFormSchema();
$ws->addFormFormatter('stub', new FormFormatterStub());
$ws->setFormFormatterName('stub');
$w = new sfWidgetFormSelect(array('choices' => array('group' => array('foo' => 'bar', 'foobar' => 'foo'))));
$w->setParent($ws);
$dom->loadHTML($w->render('foo'));
$css = new sfDomCssSelector($dom);
$t->is($css->matchSingle('#foo optgroup[label="translation[group]"] option[value="foo"]')->getValue(), 'translation[bar]', '->render() translates the options');
$t->is($css->matchSingle('#foo optgroup[label="translation[group]"] option[value="foobar"]')->getValue(), 'translation[foo]', '->render() translates the options');
// choices as a callable
$t->diag('choices as a callable');
function choice_callable()
{
    return array(1, 2, 3);
}
$w = new sfWidgetFormSelect(array('choices' => new sfCallable('choice_callable')));
$dom->loadHTML($w->render('foo'));
$css = new sfDomCssSelector($dom);
$t->is(count($css->matchAll('#foo option')->getNodes()), 3, '->render() accepts a sfCallable as a choices option');
// attributes
 /**
  * Renders the widget.
  *
  * @param  string $name        The element name
  * @param  string $value       The value selected in this widget
  * @param  array  $attributes  An array of HTML attributes to be merged with the default HTML attributes
  * @param  array  $errors      An array of errors for the field
  *
  * @return string An HTML tag string
  *
  * @see sfWidgetForm
  */
 public function render($name, $value = null, $attributes = array(), $errors = array())
 {
     if (is_null($value)) {
         $value = array();
     }
     $choices = $this->getOption('choices');
     if ($choices instanceof sfCallable) {
         $choices = $choices->call();
     }
     $associated = array();
     $unassociated = array();
     foreach ($choices as $key => $option) {
         if (in_array(strval($key), $value)) {
             $associated[$key] = $option;
         } else {
             $unassociated[$key] = $option;
         }
     }
     $size = isset($attributes['size']) ? $attributes['size'] : (isset($this->attributes['size']) ? $this->attributes['size'] : 10);
     $associatedWidget = new sfWidgetFormSelect(array('multiple' => true, 'choices' => $associated), array('size' => $size, 'class' => $this->getOption('class_select') . '-selected'));
     $associatedWidget->setParent($this->getParent());
     $unassociatedWidget = new sfWidgetFormSelect(array('multiple' => true, 'choices' => $unassociated), array('size' => $size, 'class' => $this->getOption('class_select')));
     $unassociatedWidget->setParent($this->getParent());
     return strtr($this->getOption('template'), array('%class%' => $this->getOption('class'), '%class_select%' => $this->getOption('class_select'), '%id%' => $this->generateId($name), '%label_associated%' => $this->translate($this->getOption('label_associated')), '%label_unassociated%' => $this->translate($this->getOption('label_unassociated')), '%associate%' => sprintf('<a href="#" onclick="%s">%s</a>', 'sfDoubleList.move(\'unassociated_' . $this->generateId($name) . '\', \'' . $this->generateId($name) . '\'); return false;', $this->getOption('associate')), '%unassociate%' => sprintf('<a href="#" onclick="%s">%s</a>', 'sfDoubleList.move(\'' . $this->generateId($name) . '\', \'unassociated_' . $this->generateId($name) . '\'); return false;', $this->getOption('unassociate')), '%associated%' => $associatedWidget->render($name), '%unassociated%' => $unassociatedWidget->render('unassociated_' . $name)));
 }