# # # patch "cset.cc" # from [e02b9b802566e760f15cfe37adcb26c27446b451] # to [1b8e927062fb4ba517fd3b5ce905dd7a85d0e14f] # # patch "paths.cc" # from [d3290e08f71dd807af63d32ffbefbe84c8e61757] # to [4605bdff860a8eec093c0e5b086a1915556bdf89] # ============================================================ --- cset.cc e02b9b802566e760f15cfe37adcb26c27446b451 +++ cset.cc 1b8e927062fb4ba517fd3b5ce905dd7a85d0e14f @@ -24,11 +24,10 @@ { MM(cs); - // FIXME -- normalize: + // normalize: // // add_file address@hidden + apply_delta id1->id2 // clear_attr foo:bar + set_attr foo:bar=baz - // rename foo -> foo // // possibly more? ============================================================ --- paths.cc d3290e08f71dd807af63d32ffbefbe84c8e61757 +++ paths.cc 4605bdff860a8eec093c0e5b086a1915556bdf89 @@ -990,9 +990,48 @@ BOOST_CHECK_THROW(a.may_not_initialize(), std::logic_error); } +static void test_a_path_ordering(std::string const & left, std::string const & right) +{ + MM(left); + MM(right); + split_path left_sp, right_sp; + file_path_internal(left).split(left_sp); + file_path_internal(right).split(right_sp); + I(left_sp < right_sp); +} + +static void test_path_ordering() +{ + // this ordering is very important: + // -- it is used to determine the textual form of csets and manifests + // (in particular, it cannot be changed) + // -- it is used to determine in what order cset operations can be applied + // (in particular, foo must sort before foo/bar, so that we can use it + // to do top-down and bottom-up traversals of a set of paths). + test_a_path_ordering("a", "b"); + test_a_path_ordering("a", "c"); + test_a_path_ordering("ab", "ac"); + test_a_path_ordering("a", "ab"); + test_a_path_ordering("", "a"); + test_a_path_ordering("", ".foo"); + test_a_path_ordering("foo", "foo/bar"); + // . is before / asciibetically, so sorting by strings will give the wrong + // answer on this: + test_a_path_ordering("foo/bar", "foo.bar"); + + // path_components used to be interned strings, and we used the default sort + // order, which meant that in practice path components would sort in the + // _order they were first used in the program_. So let's put in a test that + // would catch this sort of brokenness. + test_a_path_ordering("fallanopic_not_otherwise_mentioned", "xyzzy"); + test_a_path_ordering("fallanoooo_not_otherwise_mentioned_and_smaller", "fallanopic_not_otherwise_mentioned"); +} + + void add_paths_tests(test_suite * suite) { I(suite); + suite->add(BOOST_TEST_CASE(&test_path_ordering)); suite->add(BOOST_TEST_CASE(&test_null_name)); suite->add(BOOST_TEST_CASE(&test_file_path_internal)); suite->add(BOOST_TEST_CASE(&test_file_path_external_null_prefix));