# # # add_dir "tests/extended-selectors" # # add_file "tests/extended-selectors/__driver__.lua" # content [3c8ad96220f4124d1454522547da95cabb8e0d08] # # patch "selectors.cc" # from [87546db6679852f6f0bae526ca9a53c05185c8d6] # to [1255630a07641f219d29bdc847203fe8d1fbfbe8] # ============================================================ --- tests/extended-selectors/__driver__.lua 3c8ad96220f4124d1454522547da95cabb8e0d08 +++ tests/extended-selectors/__driver__.lua 3c8ad96220f4124d1454522547da95cabb8e0d08 @@ -0,0 +1,88 @@ +-- selector functions are: +-- difference(a,b) +-- lca(a,b) +-- max(a) +-- ancestors(a) +-- descendants(a) +-- parents(a) +-- children(a) +-- operators are a/b/c for 'and' and a|b|c for 'or' + +mtn_setup() + +do + local num = 0 + function ci(branch, parent, author) + num = num + 1 + if parent ~= nil + then + check(mtn("up", "-r", parent), 0, nil, false) + end + addfile("file-" .. num, "foo") + check(mtn("commit", "-b", branch, "--author", author, "-mx"), 0, nil, false) + return base_revision() + end + function merge(rev1, rev2, branch, author) + check(mtn("explicit_merge", rev1, rev2, branch, "--author", author), 0, nil, true) + local result = readfile("stderr"):match("%[merged%] (%x+)") + L("Merge result: " .. result .. "\n") + check(result:len() == 40) + return result + end + function expect(selector, ...) + check(mtn("automate", "select", selector), 0, true, nil) + local linecount = 0; + local expected = {...} + local ok = true + for line in io.lines("stdout") + do + linecount = linecount + 1 + local idx = nil + for k,v in ipairs(expected) + do + if v == line then idx = k end + end + if idx == nil + then + L("Did not expect " .. line .. "\n") + ok = false + else + expected[idx] = true + end + end + for k,v in ipairs(expected) + do + if v ~= true + then + L("Expected " .. v .. "\n") + ok = false + end + end + check(ok) + end + function approve(branch, rev) + check(mtn("approve", "-b", branch, rev), 0, nil, false) + end +end + +root = ci("testbranch", nil, "Joe") +lhs = ci("testbranch", root, "Joe") +rhs = ci("testbranch", root, "Anne") +m = merge(lhs, rhs, "testbranch", "Anne") +approve("otherbranch", lhs) +other = ci("otherbranch", lhs, "Jim") +other_2 = ci("otherbranch", other, "Jim") + +expect("b:testbranch", root, lhs, rhs, m) +expect("b:otherbranch", lhs, other, other_2) +expect("b:testbranch/b:otherbranch", lhs) +expect("b:testbranch|b:otherbranch", root, lhs, rhs, m, other, other_2) + +expect("lca(h:testbranch,h:otherbranch)", lhs) +expect("max(b:testbranch/a:Joe)", lhs) +expect("max(b:otherbranch/a:Anne)") +expect("difference(b:testbranch,a:Joe)", rhs, m) +expect("ancestors(b:otherbranch)", other, lhs, root) +expect("descendants("..lhs..")", m, other, other_2) +expect("parents(lca(h:otherbranch,h:testbranch))", root) +expect("children(lca(h:otherbranch,h:testbranch))", m, other) ============================================================ --- selectors.cc 87546db6679852f6f0bae526ca9a53c05185c8d6 +++ selectors.cc 1255630a07641f219d29bdc847203fe8d1fbfbe8 @@ -434,6 +434,7 @@ set get_ancestors(project_t frontier.erase(frontier.begin()); set p; project.db.get_revision_parents(revid, p); + p.erase(revision_id()); frontier.insert(p.begin(), p.end()); ret.insert(p.begin(), p.end()); } @@ -684,10 +685,10 @@ shared_ptr selector::create(op if (*tok == "(") { items.push_back(parse_item(*tok)); } else if (*tok == ")") { - unsigned int lparen_pos = 0; + unsigned int lparen_pos = 1; while (lparen_pos <= items.size() && items[items.size() - lparen_pos].str != "(") { - --lparen_pos; + ++lparen_pos; } E(items[items.size() - lparen_pos].str == "(", origin::user, F("selector '%s' is invalid, unmatched '('") % orig); @@ -696,12 +697,15 @@ shared_ptr selector::create(op { // looks like a function call shared_ptr to_add(new fn_selector(items[name_idx].str)); + L(FL("found function-like selector '%s' at stack position %d of %d") + % items[name_idx].str % name_idx % items.size()); + // note the closing paren is not on the item stack for (unsigned int idx = items.size() - lparen_pos + 1; - idx < items.size() - 1; idx += 2) + idx < items.size(); idx += 2) { + L(FL(" found argument at stack position %d") % idx); shared_ptr arg = items[idx].sel; - string sep = items[idx + 1].str; - E(sep == "," || (sep == ")" && idx == items.size() - 2), origin::user, + E(idx == items.size() - 1 || items[idx+1].str == ",", origin::user, F("selector '%s' is invalid, function argument doesn't look like an arg-list")); to_add->add(arg); }