Index: modules/node/content_types.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/content_types.inc,v
retrieving revision 1.116
diff -u -p -r1.116 content_types.inc
--- modules/node/content_types.inc	8 Aug 2010 13:02:37 -0000	1.116
+++ modules/node/content_types.inc	15 Aug 2010 23:21:04 -0000
@@ -323,6 +323,7 @@ function node_type_form_submit($form, &$
     return;
   }
 
+  form_state_values_clean($form_state);
   $variables = $form_state['values'];
 
   // Remove everything that's been saved already - whatever's left is assumed
@@ -333,8 +334,6 @@ function node_type_form_submit($form, &$
     }
   }
 
-  unset($variables['form_token'], $variables['op'], $variables['submit'], $variables['delete'], $variables['reset'], $variables['form_id'], $variables['form_build_id']);
-
   // Save or reset persistent variable values.
   foreach ($variables as $key => $value) {
     $variable_new = $key . '_' . $type->type;
Index: modules/simpletest/tests/menu.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/menu.test,v
retrieving revision 1.34
diff -u -p -r1.34 menu.test
--- modules/simpletest/tests/menu.test	8 Aug 2010 19:35:49 -0000	1.34
+++ modules/simpletest/tests/menu.test	16 Aug 2010 00:18:20 -0000
@@ -525,3 +525,200 @@ class MenuTreeDataTestCase extends Drupa
     return $this->assert($link1['mlid'] == $link2['mlid'], $message ? $message : t('First link is identical to second link'));
   }
 }
+
+/**
+ * Menu breadcrumbs related tests.
+ */
+class MenuBreadcrumbTestCase extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Breadcrumbs',
+      'description' => 'Tests breadcrumbs functionality.',
+      'group' => 'Menu',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    $perms = array_keys(module_invoke_all('permission'));
+    $this->admin_user = $this->drupalCreateUser($perms);
+    $this->drupalLogin($this->admin_user);
+  }
+
+  /**
+   * Tests breadcrumbs on node and administrative paths.
+   *
+   * @todo Change front page -> test "Home".
+   */
+  function testBreadCrumbs() {
+    // Prepare common base breadcrumb elements.
+    $home = array('<front>' => 'Home');
+    $admin = $home + array('admin' => t('Administer'));
+    $dashboard = $home + array('admin' => t('Dashboard'));
+    $config = $dashboard + array('admin/config' => t('Configuration'));
+    $type = 'article';
+
+    // Verify Taxonomy administration breadcrumbs.
+    $expected = $dashboard + array(
+      'admin/structure' => t('Structure'),
+    );
+    $this->assertBreadcrumb('admin/structure/taxonomy', $expected);
+
+    $expected += array(
+      'admin/structure' => t('Structure'),
+      'admin/structure/taxonomy' => t('Taxonomy'),
+    );
+    $this->assertBreadcrumb('admin/structure/taxonomy/tags', $expected);
+    $expected += array(
+      'admin/structure/taxonomy/tags' => t('Tags'),
+    );
+    $this->assertBreadcrumb('admin/structure/taxonomy/tags/edit', $expected);
+    $this->assertBreadcrumb('admin/structure/taxonomy/tags/fields', $expected);
+    $this->assertBreadcrumb('admin/structure/taxonomy/tags/add', $expected);
+
+    // Verify Node administration breadcrumbs.
+    $expected = $dashboard + array(
+      'admin/structure' => t('Structure'),
+      'admin/structure/types' => t('Content types'),
+    );
+    $this->assertBreadcrumb('admin/structure/types/add', $expected);
+    $this->assertBreadcrumb("admin/structure/types/manage/$type", $expected);
+    $expected += array(
+      'admin/structure/types/manage/$type' => t('Article'),
+    );
+    $this->assertBreadcrumb("admin/structure/types/manage/$type/fields", $expected);
+    $this->assertBreadcrumb("admin/structure/types/manage/$type/display", $expected);
+    $this->assertBreadcrumb("admin/structure/types/manage/$type/display/teaser", $expected);
+    $this->assertBreadcrumb("admin/structure/types/manage/$type/comment/fields", $expected);
+    $this->assertBreadcrumb("admin/structure/types/manage/$type/comment/display", $expected);
+    $this->assertBreadcrumb("admin/structure/types/manage/$type/delete", $expected);
+
+    // Verify Filter text format administration breadcrumbs.
+    $format = db_query_range("SELECT * FROM {filter_format}", 1, 1)->fetch();
+    $format_id = $format->format;
+    $expected = $config + array(
+      'admin/config/content' => t('Content authoring'),
+    );
+    $this->assertBreadcrumb('admin/config/content/formats', $expected);
+
+    $expected += array(
+      'admin/config/content/formats' => t('Text formats'),
+    );
+    $this->assertBreadcrumb('admin/config/content/formats/add', $expected);
+    $this->assertBreadcrumb("admin/config/content/formats/$format_id", $expected);
+    $expected += array(
+      'admin/config/content/formats/$format_id' => $format->name,
+    );
+    $this->assertBreadcrumb("admin/config/content/formats/$format/delete", $expected);
+
+    // Verify node breadcrumbs (without menu link).
+    $node1 = $this->drupalCreateNode();
+    $nid1 = $node1->nid;
+    $expected = $home;
+    $this->assertBreadcrumb("node/$nid1", $expected);
+    $expected += array(
+      "node/$nid1" => check_plain($node1->title),
+    );
+    $this->assertBreadcrumb("node/$nid1/edit", $expected);
+
+    // Verify that node listing page still contains "Home" only.
+    $expected = $home;
+    $this->assertBreadcrumb('node', $expected);
+
+    // Verify node breadcrumbs (in menu).
+    // Do this separately for Main menu and Navigation menu, since only the
+    // latter is a preferred menu by default.
+    // @todo Also test all themes? Manually testing led to the suspicion that
+    //   breadcrumbs may differ, possibly due to template.php overrides.
+    $menus = array('main-menu', 'navigation');
+    foreach ($menus as $menu) {
+      // Alter node type menu settings.
+      variable_set("menu_options_$type", array($menu => $menu));
+      variable_set("menu_parent_$type", "$menu:0");
+
+      $node2 = $this->drupalCreateNode(array('menu' => array(
+        'enabled' => 1,
+        'link_title' => $this->randomString(),
+        'description' => '',
+        'menu_name' => $menu,
+        'plid' => 0,
+      )));
+      $nid2 = $node2->nid;
+
+      $expected = $home;
+      $this->assertBreadcrumb("node/$nid2", $expected);
+      $expected += array(
+        "node/$nid2" => check_plain($node2->title),
+      );
+      $this->assertBreadcrumb("node/$nid2/edit", $expected);
+
+      $node3 = $this->drupalCreateNode(array('menu' => array(
+        'enabled' => 1,
+        'link_title' => $this->randomString(),
+        'description' => '',
+        'menu_name' => $menu,
+        'plid' => $node2->menu['mlid'],
+      )));
+      $nid3 = $node3->nid;
+
+      $this->assertBreadcrumb("node/$nid2", $expected);
+      $expected += array(
+        "node/$nid3" => check_plain($node3->title),
+      );
+      $this->assertBreadcrumb("node/$nid2/edit", $expected);
+
+      // Verify that node listing page still contains "Home" only.
+      $expected = $home;
+      $this->assertBreadcrumb('node', $expected);
+    }
+
+    // @todo Add a taxonomy term + Navigation menu link, verify expected BC.
+    // @todo Add a Navigation menu link for $this->admin_user, verify expected BC.
+  }
+
+  /**
+   * Assert that a given path shows certain breadcrumb links.
+   *
+   * @param string $goto
+   *   A system path to pass to DrupalWebTestCase::drupalGet().
+   * @param array $links
+   *   An associative array whose keys are expected breadcrumb link paths and
+   *   whose values are expected breadcrumb link texts.
+   */
+  protected function assertBreadcrumb($goto, $links) {
+    if (isset($goto)) {
+      $this->drupalGet($goto);
+    }
+    // Compare paths with actual breadcrumb.
+    $parts = $this->getParts();
+    $pass = TRUE;
+    foreach ($links as $path => $title) {
+      $url = url($path);
+      $part = array_shift($parts);
+      $pass = ($pass && $part['href'] === $url && $part['text'] === $title);
+    }
+    // No parts must be left, or an expected "Home" will always pass.
+    $pass = ($pass && empty($parts));
+
+    $this->assertTrue($pass, t('Breadcrumb %parts found on @path.', array(
+      '%parts' => implode(' » ', $links),
+      '@path' => $goto,
+    )));
+  }
+
+  /**
+   * Returns the breadcrumb contents of the current page in the internal browser.
+   */
+  protected function getParts() {
+    $parts = array();
+    $elements = $this->xpath('//div[@class="breadcrumb"]/a');
+    foreach ($elements as $element) {
+      $parts[] = array(
+        'text' => (string) $element,
+        'href' => (string) $element['href'],
+        'title' => (string) $element['title'],
+      );
+    }
+    return $parts;
+  }
+}
