Start work on randomized changed-region testing
Signed-off-by: Nathan Sobo <nathan@github.com>
This commit is contained in:
parent
591fcc980c
commit
eb5dda75c4
2 changed files with 126 additions and 0 deletions
110
spec/helpers/scope_sequence.cc
Normal file
110
spec/helpers/scope_sequence.cc
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
#include "./scope_sequence.h"
|
||||
|
||||
#include "bandit/bandit.h"
|
||||
#include <sstream>
|
||||
#include "helpers/stream_methods.h"
|
||||
#include "helpers/point_helpers.h"
|
||||
|
||||
using std::string;
|
||||
using std::cout;
|
||||
|
||||
static void append_text_to_scope_sequence(ScopeSequence *sequence,
|
||||
ScopeStack *current_scopes,
|
||||
const std::string &text,
|
||||
size_t length) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
string character(1, text[sequence->size()]);
|
||||
sequence->push_back(*current_scopes);
|
||||
sequence->back().push_back("'" + character + "'");
|
||||
}
|
||||
}
|
||||
|
||||
static void append_to_scope_sequence(ScopeSequence *sequence,
|
||||
ScopeStack *current_scopes,
|
||||
TSNode node, TSDocument *document,
|
||||
const std::string &text) {
|
||||
string scope = ts_node_type(node, document);
|
||||
current_scopes->push_back(scope);
|
||||
size_t child_count = ts_node_child_count(node);
|
||||
if (child_count > 0) {
|
||||
size_t previous_child_end = ts_node_start_char(node);
|
||||
for (size_t i = 0; i < child_count; i++) {
|
||||
TSNode child = ts_node_child(node, i);
|
||||
size_t child_start = ts_node_start_char(child);
|
||||
size_t spacing = child_start - previous_child_end;
|
||||
append_text_to_scope_sequence(sequence, current_scopes, text, spacing);
|
||||
append_to_scope_sequence(sequence, current_scopes, child, document, text);
|
||||
previous_child_end = ts_node_end_char(child);
|
||||
}
|
||||
size_t spacing = ts_node_end_char(node) - previous_child_end;
|
||||
append_text_to_scope_sequence(sequence, current_scopes, text, spacing);
|
||||
} else {
|
||||
size_t length = ts_node_end_char(node) - ts_node_start_char(node);
|
||||
append_text_to_scope_sequence(sequence, current_scopes, text, length);
|
||||
}
|
||||
current_scopes->pop_back();
|
||||
}
|
||||
|
||||
ScopeSequence build_scope_sequence(TSDocument *document, const std::string &text) {
|
||||
ScopeSequence sequence;
|
||||
ScopeStack current_scopes;
|
||||
TSNode node = ts_document_root_node(document);
|
||||
append_to_scope_sequence(&sequence, ¤t_scopes, node, document, text);
|
||||
AssertThat(sequence.size(), Equals(text.size()));
|
||||
return sequence;
|
||||
}
|
||||
|
||||
bool operator<=(const TSPoint &left, const TSPoint &right) {
|
||||
if (left.row < right.row)
|
||||
return true;
|
||||
else if (left.row == right.row)
|
||||
return left.column <= right.column;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void verify_changed_ranges(const ScopeSequence &old_sequence, const ScopeSequence &new_sequence,
|
||||
const string &text, TSRange *ranges, size_t range_count) {
|
||||
TSPoint current_position = {0, 0};
|
||||
for (size_t i = 0; i < text.size(); i++) {
|
||||
if (text[i] == '\n') {
|
||||
current_position.row++;
|
||||
current_position.column = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
const ScopeStack &old_scopes = old_sequence[i];
|
||||
const ScopeStack &new_scopes = new_sequence[i];
|
||||
if (old_scopes != new_scopes) {
|
||||
bool found_containing_range = false;
|
||||
for (size_t j = 0; j < range_count; j++) {
|
||||
TSRange range = ranges[j];
|
||||
if (range.start <= current_position && current_position <= range.end) {
|
||||
found_containing_range = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_containing_range) {
|
||||
std::stringstream message_stream;
|
||||
message_stream << "Found changed scope outside of any invalidated range;\n";
|
||||
message_stream << "Position: " << current_position << "\n";
|
||||
size_t line_start_index = i - current_position.column;
|
||||
size_t line_end_index = text.find_first_of('\n', i);
|
||||
message_stream << "Line: " << text.substr(line_start_index, line_end_index - line_start_index) << "\n";
|
||||
for (size_t j = 0; j < current_position.column + string("Line: ").size(); j++)
|
||||
message_stream << " ";
|
||||
message_stream << "^\n";
|
||||
message_stream << "Old scopes: " << old_scopes << "\n";
|
||||
message_stream << "New scopes: " << new_scopes << "\n";
|
||||
message_stream << "Invalidated ranges:\n";
|
||||
for (size_t j = 0; j < range_count; j++) {
|
||||
message_stream << " " << ranges[i] << "\n";
|
||||
}
|
||||
Assert::Failure(message_stream.str());
|
||||
}
|
||||
}
|
||||
|
||||
current_position.column++;
|
||||
}
|
||||
}
|
||||
16
spec/helpers/scope_sequence.h
Normal file
16
spec/helpers/scope_sequence.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef HELPERS_SCOPE_SEQUENCE_H_
|
||||
#define HELPERS_SCOPE_SEQUENCE_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "tree_sitter/runtime.h"
|
||||
|
||||
typedef std::string Scope;
|
||||
typedef std::vector<Scope> ScopeStack;
|
||||
typedef std::vector<ScopeStack> ScopeSequence;
|
||||
|
||||
ScopeSequence build_scope_sequence(TSDocument *document, const std::string &text);
|
||||
|
||||
void verify_changed_ranges(const ScopeSequence &old, const ScopeSequence &new_sequence, const std::string &text, TSRange *ranges, size_t range_count);
|
||||
|
||||
#endif // HELPERS_SCOPE_SEQUENCE_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue