aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Walch <florian@fwalch.com>2014-10-19 10:28:00 +0200
committerThiago de Arruda <tpadilha84@gmail.com>2014-11-04 11:38:06 -0300
commitbc6ac59928bb9982a9bf745d29f1db417574a45d (patch)
tree9824903fb43107532342ccadab88f6d9026bd597
parent5f99be1efe7eff66c947e10eeb6138bb06f070d2 (diff)
downloadrneovim-bc6ac59928bb9982a9bf745d29f1db417574a45d.tar.gz
rneovim-bc6ac59928bb9982a9bf745d29f1db417574a45d.tar.bz2
rneovim-bc6ac59928bb9982a9bf745d29f1db417574a45d.zip
Add legacy test conversion script.
-rwxr-xr-xscripts/legacy2luatest.pl262
1 files changed, 262 insertions, 0 deletions
diff --git a/scripts/legacy2luatest.pl b/scripts/legacy2luatest.pl
new file mode 100755
index 0000000000..0628ac0a1d
--- /dev/null
+++ b/scripts/legacy2luatest.pl
@@ -0,0 +1,262 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use 5.010;
+use autodie;
+
+use File::Basename;
+use File::Spec::Functions;
+
+sub read_in_file {
+ my $in_file = $_[0];
+
+ # Will contain lines before first STARTTEST
+ # as Lua comments.
+ my @description_lines = ();
+
+ # Will contain alternating blocks of lines of textual input
+ # (text between ENDTEST and EOF/next STARTTEST) and test commands
+ # (commands between STARTTEST and ENDTEST) as Lua code.
+ my @test_body_lines = ();
+
+ # Will contain current command block, i.e. lines
+ # between STARTTEST and ENDTEST.
+ my @command_lines = ();
+
+ # Will contain current input block, i.e. lines
+ # between ENDTEST and STARTTEST.
+ my @input_lines = ();
+
+ open my $in_file_handle, '<', $in_file;
+
+ use constant EMIT_DESCRIPTION => 0;
+ use constant EMIT_COMMAND => 1;
+ use constant EMIT_INPUT => 2;
+ use constant END_INPUT => 3;
+
+ my %states = (
+ # Add test description to @description_lines.
+ EMIT_DESCRIPTION() => sub {
+ if (/^STARTTEST/) {
+ return EMIT_COMMAND;
+ }
+
+ # If not an empty line, emit as Lua comment.
+ if (!/^$/) {
+ push @description_lines, '-- ' . $_;
+ }
+
+ return EMIT_DESCRIPTION;
+ },
+ # Add test commands to @command_lines.
+ EMIT_COMMAND() => sub {
+ if (/^ENDTEST/) {
+ return EMIT_INPUT;
+ }
+
+ # If line starts with ':"', emit a comment.
+ if (/^:"/) {
+ # If it's an empty comment, just add an empty line
+ # to improve readability.
+ push @command_lines, (/^$/ ? '' : '-- ' . $_);
+ } else {
+ # Extract possible inline comment.
+ if (/^[^"]*"[^"]*$/) {
+ # Remove command part and prepended whitespace.
+ s/^(.*?)\s*"\s*//;
+
+ # Capitalize first character and emit as Lua comment.
+ my $comment = '-- ' . ucfirst $_;
+
+ # Add trailing dot if not already there.
+ $comment .= '.' unless $comment =~ /\.$/;
+
+ push @command_lines, '';
+ push @command_lines, $comment;
+
+ # Set implicit variable to command without comment.
+ $_ = $1;
+ }
+
+ # Only continue if remaining command is not empty.
+ if (!/^:?\s*$/) {
+ # Replace terminal escape characters with <esc>.
+ s/\e/<esc>/g;
+
+ my $startstr = "'";
+ my $endstr = "'";
+
+ # If line contains single quotes or backslashes, use double
+ # square brackets to wrap string.
+ if (/'/ || /\\/) {
+ $startstr = '[[';
+ $endstr = ']]';
+ }
+
+ # Emit 'feed' if not a search ('/') or ex (':') command.
+ if (!/^\// && !/^:/) {
+ # If command does not end with <esc>, insert trailing <cr>.
+ my $command = 'feed(' . $startstr . $_;
+ $command .= '<cr>' unless /<esc>$/;
+ $command .= $endstr . ')';
+
+ push @command_lines, $command;
+ } else {
+ # Remove prepending ':'.
+ s/^://;
+ push @command_lines, 'execute(' . $startstr . $_ . $endstr . ')';
+ }
+ }
+ }
+
+ return EMIT_COMMAND;
+ },
+ # Add input to @input_lines.
+ EMIT_INPUT() => sub {
+ if (/^STARTTEST/) {
+ return END_INPUT;
+ }
+
+ push @input_lines, ' ' . $_;
+ return EMIT_INPUT;
+ },
+ # The END_INPUT state is used to push lines from current
+ # input and command blocks into @test_body_lines
+ # in the correct order.
+ END_INPUT() => sub {
+ # Only keep first input line if it is not empty.
+ my $first_input_line = shift @input_lines;
+ if ($first_input_line =~ /^$/) {
+ unshift @input_lines, $first_input_line;
+ }
+
+ # If there are input lines left, wrap them with
+ # `insert` command and add before the previous command
+ # block.
+ if (@input_lines) {
+ my $last_input_line = pop @input_lines;
+ unshift @command_lines, '';
+ unshift @command_lines, $last_input_line . ']])';
+ unshift @command_lines, @input_lines;
+ unshift @command_lines, "insert([[";
+
+ push @test_body_lines, @command_lines;
+
+ @command_lines = ();
+ @input_lines = ();
+ }
+
+ return EMIT_COMMAND;
+ }
+ );
+
+ my $state = EMIT_DESCRIPTION;
+
+ while (<$in_file_handle>) {
+ # Remove trailing newline character and process line.
+ chomp;
+ $state = $states{$state}->($_);
+ }
+
+ # If not all input lines have been processed,
+ # do it now.
+ if (@input_lines) {
+ $states{END_INPUT()}->();
+ }
+
+ close $in_file_handle;
+
+ return (\@description_lines, \@test_body_lines);
+}
+
+sub read_ok_file {
+ my $ok_file = $_[0];
+ my @assertions = ();
+
+ if (-f $ok_file) {
+ push @assertions, '';
+ push @assertions, "-- Assert buffer contents.";
+ push @assertions, "expect([[";
+
+ open my $ok_file_handle, '<', $ok_file;
+
+ while (<$ok_file_handle>) {
+ # Remove trailing newline character and process line.
+ chomp;
+ push @assertions, ' ' . $_;
+ }
+
+ close $ok_file_handle;
+
+ $assertions[-1] .= "]])";
+ }
+
+ return \@assertions;
+}
+
+my $legacy_testfile = $ARGV[0];
+my $out_dir = $ARGV[1];
+
+if ($#ARGV != 1) {
+ say "Convert a legacy Vim test to a Neovim lua spec.";
+ say '';
+ say "Usage: $0 legacy-testfile output-directory";
+ say '';
+ say "legacy-testfile: Path to .in or .ok file.";
+ say "output-directory: Directory where Lua spec will be saved to.";
+ say '';
+ say "Note: Only works reliably for fairly simple tests.";
+ say " Manual adjustments to generated spec files are required.";
+ exit 1;
+}
+
+my @legacy_suffixes = ('.in', '.ok');
+my ($test_name, $base_path, $suffix) = fileparse($legacy_testfile, @legacy_suffixes);
+my $in_file = catfile($base_path, $test_name . '.in');
+my $ok_file = catfile($base_path, $test_name . '.ok');
+
+my $spec_file = catfile($out_dir, $test_name . '_spec.lua');
+
+if (! -f $in_file) {
+ say "Test input file $in_file not found.";
+ exit 2;
+}
+
+if (! -d $out_dir) {
+ say "Output directory $out_dir does not exist.";
+ exit 3;
+}
+
+if (-f $spec_file) {
+ say "Output file $spec_file already exists.";
+ exit 4;
+}
+
+# Read .in and .ok files.
+my ($description_lines, $test_body_lines) = read_in_file $in_file;
+my $assertion_lines = read_ok_file $ok_file;
+
+# Append assertions to test body.
+push @{$test_body_lines}, @{$assertion_lines} if @{$assertion_lines};
+
+# Write spec file.
+open my $spec_file_handle, ">", $spec_file;
+
+print $spec_file_handle <<"EOS";
+@{[join "\n", @{$description_lines}]}
+
+local helpers = require('test.functional.helpers')
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute, expect = helpers.execute, helpers.expect
+
+describe('$test_name', function()
+ setup(clear)
+
+ it('is working', function()
+@{[join "\n", map { /^$/ ? '' : ' ' . $_ } @{$test_body_lines}]}
+ end)
+end)
+EOS
+
+close $spec_file_handle;