Skip to content
8 changes: 8 additions & 0 deletions indra/llui/llcombobox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,14 @@ void LLComboBox::onCommit()
mTextEntry->setValue(label);
mTextEntry->setTentative(false);
}
// Chosen or typed: the value is the control's own now, whoever had
// written it before.
mUnset = false;
setControlValue(item->getValue());
}
else if (mAllowTextEntry)
{
mUnset = false;
setControlValue(mTextEntry->getValue());
}
else
Expand Down Expand Up @@ -465,6 +469,10 @@ void LLComboBox::setUnset(bool unset)

void LLComboBox::updateLabel()
{
// An item chosen is shown as settled, and is: whoever had written the
// value before, it is the control's own now.
mUnset = false;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

// Update the combo editor with the selected
// item label.
if (mTextEntry)
Expand Down
2 changes: 2 additions & 0 deletions indra/llui/tests/alanchoredranges_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ namespace
[&gone](Hint& h) { gone.push_back(h.name); });
{
INFO("before stays, after moves");
REQUIRE(hints.size() == 3);
CHECK(hints[0].name == "inside");
CHECK(hints[1].name == "before");
CHECK(hints[1].at == ALTextPos(0, 4));
Expand Down Expand Up @@ -168,6 +169,7 @@ namespace
{
INFO("past the edit's line, not looked at, and where it was");
CHECK(current == 3);
REQUIRE(matches.size() == 4);
CHECK(matches[3] == on(1, 3, 5));
}
matches.apply(doc.replace(on(1, 3, 5), "E"), &current);
Expand Down
5 changes: 4 additions & 1 deletion indra/llui/tests/alcanvasview_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1147,8 +1147,11 @@ namespace
UNSCOPED_INFO("and down");
CHECK(area->getDocPosVertical() == 40);

// panGesture() is whether a left press pans, which the space bar
// held makes it too: asked before the surface says it drags and
// after, it shows the saying is what changed it.
UNSCOPED_INFO("a plain surface does not drag by the left button");
CHECK_FALSE(canvas->dragPans());
CHECK_FALSE(canvas->panGesture());
canvas->setDragPans(true);
UNSCOPED_INFO("until it says so");
CHECK(canvas->panGesture());
Expand Down
18 changes: 11 additions & 7 deletions indra/llui/tests/alchangepeek_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ namespace
TEST_CASE_METHOD(alchangepeek_data, "alchangepeek: take_back reverts a change as one undo step and other edits close it", "[alchangepeek]")
{
ALCodeEditor& e = make("a\nb\nc\nd\ne", "a\nB\nc\nx\nd");
e.peekChange(1);
CHECK(e.peekChange(1));
ALChangePeek& peek = *e.changePeek();
press(peek, "take_back");
UNSCOPED_INFO("made as saved");
Expand Down Expand Up @@ -269,7 +269,7 @@ namespace
TEST_CASE_METHOD(alchangepeek_data, "alchangepeek: changed words are marked in the peek and the editor until it closes", "[alchangepeek]")
{
ALCodeEditor& e = make("integer count = 1;\nstring s;", "integer total = 2;\nstring s;");
e.peekChange(0);
CHECK(e.peekChange(0));
ALChangePeek& peek = *e.changePeek();
const auto has = [](const ALTextRange& range, S32 line, S32 begin, S32 end) {
return range.begin.line == line && range.begin.column <= begin && range.end.column >= end;
Expand All @@ -294,7 +294,7 @@ namespace
editor->die();
editor = nullptr;
ALCodeEditor& f = make("a\nb", "a\nput in\nb");
f.peekChange(1);
CHECK(f.peekChange(1));
{
INFO("nothing marked");
CHECK(f.highlights(ALCodeEditor::Highlight::Change).empty());
Expand Down Expand Up @@ -497,6 +497,7 @@ namespace
INFO("undone: again, three");
CHECK(e.perform(ALEditorCommand::Undo));
CHECK(e.changesSinceSaved() != edited);
REQUIRE(e.changesSinceSaved());
CHECK(e.changesSinceSaved()->changes.size() == 3);
}
e.resetDirty();
Expand All @@ -507,8 +508,11 @@ namespace
}
// Changed by its document, which no journal is told of: again.
e.document().replace(ALTextRange(ALTextPos(0, 0), ALTextPos(0, 0)), "z");
UNSCOPED_INFO("the text as it is");
CHECK(e.changesSinceSaved()->now.front() == "za");
{
INFO("the text as it is");
REQUIRE(e.changesSinceSaved());
CHECK(e.changesSinceSaved()->now.front() == "za");
}
}

TEST_CASE_METHOD(alchangepeek_data, "alchangepeek: an edit above a peek that adds or takes lines closes it leaving no gap", "[alchangepeek]")
Expand Down Expand Up @@ -606,8 +610,8 @@ namespace
CHECK_FALSE(peek.isOpen());
CHECK(e.lineAnnotation(2).gap == 0);
}
UNSCOPED_INFO("closed, F7 is the text's again");
CHECK_FALSE(peek.isOpen());
UNSCOPED_INFO("closed, F7 is the text's again: with no misspelling to go to, nothing takes it");
CHECK_FALSE(e.handleKeyHere(KEY_F7, MASK_NONE));

e.setModalKeymap(std::make_unique<ALVimKeymap>());
{
Expand Down
3 changes: 2 additions & 1 deletion indra/llui/tests/alchoicelist_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ namespace
CHECK(std::abs(note0 - note2) < 1.f);
UNSCOPED_INFO("past the widest text");
CHECK(note2 > v.layout().xOf(2, 10));
UNSCOPED_INFO("two styles a line: the note's face on every line, and the ink where one is given");
UNSCOPED_INFO("a style a line, the note's face: no choice here has an ink of its own");
CHECK(v.styles().size() == size_t(3));
v.moveChoice(1, true);
UNSCOPED_INFO("down one");
Expand Down Expand Up @@ -206,6 +206,7 @@ namespace
CHECK(v.document().line(1) == std::string("odd one\t(string)"));
UNSCOPED_INFO("the choice below is on its own line");
CHECK(v.document().line(2) == std::string("last\t "));
REQUIRE(v.choices().size() == size_t(3));
UNSCOPED_INFO("the words handed back as given");
CHECK(v.choices()[0].note == std::string("for each\nitem in a list"));
S32 x, y;
Expand Down
47 changes: 36 additions & 11 deletions indra/llui/tests/alcodeeditor_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ namespace
CHECK(e.markAt(2) == ALCodeEditor::Mark::Error);
CHECK(e.markAt(1) == ALCodeEditor::Mark::None);
}
REQUIRE_FALSE(e.decorations().empty());
UNSCOPED_INFO("the decoration slid");
CHECK(e.decorations().front().range.begin.line == 3);
e.document().replace(ALTextRange(ALTextPos(3, 0), ALTextPos(3, 2)), "TH");
Expand Down Expand Up @@ -318,7 +319,7 @@ namespace
type("u");
{
INFO("still open, narrowed");
CHECK(e.completionOpen());
REQUIRE(e.completionOpen());
CHECK(e.completions()[0].text == "count");
}
key(KEY_RETURN);
Expand Down Expand Up @@ -351,7 +352,7 @@ namespace
type(" cu");
{
INFO("the provider's word");
CHECK(e.completionOpen());
REQUIRE(e.completionOpen());
CHECK(e.completions()[0].text == "custom");
CHECK(e.completions()[0].detail == "made up");
}
Expand Down Expand Up @@ -394,7 +395,7 @@ namespace
type("a");
{
INFO("narrowing keeps it");
CHECK(e.completionOpen());
REQUIRE(e.completionOpen());
CHECK(e.completions()[0].text == "abacus");
}
UNSCOPED_INFO("no new request while narrowing");
Expand Down Expand Up @@ -1218,10 +1219,12 @@ namespace
REQUIRE(e.completions().size() == 4);
CHECK(e.completions()[0].text == "sayAgain");
}
REQUIRE(e.chosenCompletion() >= 0);
UNSCOPED_INFO("the choice is still SAY_CHANNEL");
CHECK(e.completions()[e.chosenCompletion()].text == std::string("SAY_CHANNEL"));
// More typed starts from the best.
type("i");
REQUIRE(e.chosenCompletion() >= 0);
UNSCOPED_INFO("narrowed to the best");
CHECK(e.completions()[e.chosenCompletion()].text == std::string("saying"));
key(KEY_ESCAPE);
Expand All @@ -1242,7 +1245,7 @@ namespace
}
});
type("llOld");
CHECK(e.completionOpen());
REQUIRE(e.completionOpen());
CHECK(e.completions()[0].deprecated);
key(KEY_RETURN);
UNSCOPED_INFO("with its brackets and its parameter");
Expand Down Expand Up @@ -1271,6 +1274,7 @@ namespace
const S32 y = text.mTop - e.layout().rowHeight() / 2;
e.handleHover(x, y, MASK_NONE);
CHECK(e.handleToolTip(x, y, MASK_NONE));
REQUIRE(e.cardShown());
const ALTextView& card = *e.card();
UNSCOPED_INFO("the problem, a blank, then the word");
CHECK(card.text() == std::string("Too few arguments\n\ninteger llSay(integer channel, string msg)\nSays something."));
Expand Down Expand Up @@ -2188,6 +2192,7 @@ namespace
CHECK(told.back().first != was);
}
e.noteFixes(was, { "stale", "stale" });
REQUIRE(e.fixes().size() == 2);
UNSCOPED_INFO("an old making's dropped");
CHECK(e.fixes()[0].note.empty());
e.noteFixes(told.back().first, { "one" });
Expand Down Expand Up @@ -2600,7 +2605,9 @@ namespace
type("\n");
{
INFO("each slid");
REQUIRE_FALSE(e.highlights(H::References).empty());
CHECK(e.highlights(H::References)[0].begin == ALTextPos(1, 8));
REQUIRE_FALSE(e.highlights(H::Block).empty());
CHECK(e.highlights(H::Block)[0].begin == ALTextPos(2, 8));
}
e.clearHighlights();
Expand All @@ -2612,6 +2619,7 @@ namespace
later.range = ALTextRange(ALTextPos(1, 0), ALTextPos(1, 13));
later.message = "later";
e.setDecorations({ worst, later });
REQUIRE(e.decorations().size() == 2);
UNSCOPED_INFO("as they lie");
CHECK(e.decorations()[0].message == "later");
const std::vector<const ALCodeEditor::Decoration*> listed = e.decorationsOn(1);
Expand Down Expand Up @@ -2707,6 +2715,7 @@ namespace
type("nt");
UNSCOPED_INFO("asked once for the word, narrowed as it grew");
CHECK(asked == 1);
REQUIRE_FALSE(e.completions().empty());
UNSCOPED_INFO("the word typed out first");
CHECK(e.completions()[0].text == std::string("count"));
key(KEY_RETURN);
Expand Down Expand Up @@ -3176,11 +3185,13 @@ namespace
e.setCaret(ALTextPos(0, 2));
e.showSignature(ALTextPos(0, 2), forms);
key(KEY_DOWN);
REQUIRE(e.signature() != nullptr);
UNSCOPED_INFO("Down: the next form");
CHECK(e.signature()->label == std::string("f(string text)"));
UNSCOPED_INFO("the caret where it was");
CHECK(e.caret() == ALTextPos(0, 2));
key(KEY_DOWN);
REQUIRE(e.signature() != nullptr);
UNSCOPED_INFO("round to the first");
CHECK(e.signature()->label == sig.label);
}
Expand Down Expand Up @@ -3268,6 +3279,7 @@ namespace
p.bracket_color_2 = LLUIColor(LLColor4::green);
p.bracket_color_3 = LLUIColor(LLColor4::blue);
editor = LLUICtrlFactory::create<ALCodeEditor>(p);
made.push_back(editor);
editor->setFont(LLFontGL::getFontMonospace());
std::vector<ALCodeEditor::SemanticToken> lit;
for (size_t at = text.find('x'); at != std::string::npos; at = text.find('x', at + 1))
Expand Down Expand Up @@ -3299,7 +3311,10 @@ namespace
}
};

// A colour for each character: the line is ASCII in the monospace
// face, one glyph to a character.
const std::vector<LLColor4U> all = whole_of();
REQUIRE(all.size() == text.size());
// What the line is coloured with: a bracket at each depth, the
// analyzer's colour in code, and the grammar's in the string.
const S32 first_open = static_cast<S32>(text.find('('));
Expand All @@ -3325,6 +3340,7 @@ namespace

editor->setWordWrap(false);
const ALTextLayout::Line& one = editor->layout().line(0);
REQUIRE_FALSE(one.rows.empty());
for (F32 from = 0.f; from < one.width; from += 1500.f)
{
CAPTURE(from);
Expand All @@ -3337,6 +3353,7 @@ namespace
editor->setCaret(ALTextPos(0, 0));
editor->insertText("(");
const std::vector<LLColor4U> deeper = whole_of();
REQUIRE(deeper.size() == text.size() + 1);
UNSCOPED_INFO("the outer bracket one deeper");
CHECK(deeper[static_cast<size_t>(first_open) + 1] == LLColor4U(LLColor4::green));
editor->setWordWrap(true);
Expand Down Expand Up @@ -3784,7 +3801,7 @@ namespace
type("--!st");
{
INFO("open after --!");
CHECK(e.completionOpen());
REQUIRE(e.completionOpen());
CHECK(e.completions()[0].text == "strict");
}
key(KEY_TAB);
Expand Down Expand Up @@ -3835,6 +3852,7 @@ namespace
INFO("open at the quote, asked of nothing yet");
CHECK(e.completionOpen());
CHECK(e.completions().size() == 3);
REQUIRE_FALSE(asked.empty());
CHECK(asked.back().empty());
}
type("li");
Expand All @@ -3857,6 +3875,7 @@ namespace
CHECK(requested.back() == "lib/");
}
type("ut");
REQUIRE_FALSE(e.completions().empty());
UNSCOPED_INFO("narrowed in the folder");
CHECK(e.completions()[0].text == std::string("util"));
key(KEY_TAB);
Expand All @@ -3880,7 +3899,7 @@ namespace
type("--#include \"m");
{
INFO("an include's name too");
CHECK(e.completionOpen());
REQUIRE(e.completionOpen());
CHECK(e.completions()[0].text == "main");
}
key(KEY_ESCAPE);
Expand All @@ -3904,7 +3923,7 @@ namespace
type("require(\"ma");
{
INFO("open in a string not closed");
CHECK(e.completionOpen());
REQUIRE(e.completionOpen());
CHECK(e.completions()[0].text == "main");
}
key(KEY_TAB);
Expand All @@ -3918,7 +3937,7 @@ namespace
type("\"ma");
{
INFO("open before what follows");
CHECK(e.completionOpen());
REQUIRE(e.completionOpen());
CHECK(e.completions()[0].text == "main");
}
key(KEY_TAB);
Expand Down Expand Up @@ -3982,6 +4001,7 @@ namespace
INFO("open at the quote, asked of nothing yet");
CHECK(e.completionOpen());
CHECK(e.completions().size() == 3);
REQUIRE_FALSE(asked.empty());
CHECK(asked.back().empty());
}
type("Door ");
Expand Down Expand Up @@ -5033,18 +5053,23 @@ namespace
}
}
}
// The first line the layout hides for the folds where no folded
// block does, or shows where one does: one check a step, not one
// a line.
S32 hidden = 0;
S32 wrong = -1;
for (S32 l = 0; l < lines; ++l)
{
const bool by_folds = e.layout().hiddenBy(l, By::Folds);
const bool wanted = folded[static_cast<size_t>(l)] != 0;
hidden += by_folds ? 1 : 0;
if (by_folds != wanted)
if (by_folds != wanted && wrong < 0)
{
CAPTURE(l);
REQUIRE(by_folds == wanted);
wrong = l;
}
}
UNSCOPED_INFO("each line hidden for the folds just where a folded block hides it");
REQUIRE(wrong == -1);
UNSCOPED_INFO("as many hidden for the folds as the layout counts");
REQUIRE(e.layout().hiddenCount(By::Folds) == hidden);
folded_steps += hidden > 0 ? 1 : 0;
Expand Down
14 changes: 10 additions & 4 deletions indra/llui/tests/alcolorfield_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,11 @@ namespace
});
field->setValue("$Accent");
LLColor4 shown;
UNSCOPED_INFO("the field resolves its own name");
CHECK(field->resolved(shown));
{
INFO("the field resolves its own name");
CHECK(field->resolved(shown));
CHECK(shown == LLColor4(0.f, 0.5f, 1.f, 1.f));
}
field->handleMouseDown(4, 10, MASK_NONE);

ALColorPicker* picker = gFloaterView->findChild<ALColorPicker>("picker", true);
Expand All @@ -323,13 +326,16 @@ namespace
// The first swatch is the caller's own name.
grid->handleMouseDown(5 + 14, grid->getRect().getHeight() - 5 - 14, MASK_NONE);
LLFloater* popover = grid->getParentByType<LLFloater>();
UNSCOPED_INFO("the grid is in the popover");
REQUIRE(popover != nullptr);
UNSCOPED_INFO("the caller's name comes first");
CHECK(popover->getTitle() == std::string("$Accent"));
field->die();
}

// A name means what the table says now: the swatch follows a colour
// changed elsewhere without the text having changed.
// A name means what the table says now: what the field resolves it to,
// which is what its swatch is drawn in, follows a colour changed
// elsewhere without the text having changed.
TEST_CASE_METHOD(alcolorfield_data, "alcolorfield: a name resolves to its colour as the table has it now", "[alcolorfield]")
{
if (!ui.ok())
Expand Down
Loading
Loading