fzy
terminal fuzzy finder picker
git clone https://9o.is/git/fzy.git
commit 32a413a698883be1e64ebc3a37ad4b22dbd5eaac parent cf431f66952621d7aa03e8149f74917bee2b0fb0 Author: John Hawthorn <john.hawthorn@gmail.com> Date: Sat, 26 Jul 2014 19:51:50 -0700 Replace ruby tests with some C Ruby tests were a nice way to start, and it was nice to borrow some from selecta. However, it's going to be much easier to write tests in the same language as the implementation. Diffstat:
| M | .gitignore | | | 2 | +- |
| M | Makefile | | | 12 | +++++++----- |
| A | fzytest.c | | | 42 | ++++++++++++++++++++++++++++++++++++++++++ |
| D | test.rb | | | 54 | ------------------------------------------------------ |
| D | testscore.c | | | 22 | ---------------------- |
5 files changed, 50 insertions(+), 82 deletions(-)
diff --git a/.gitignore b/.gitignore @@ -1,3 +1,3 @@ fzy -testscore +fzytest *.o diff --git a/Makefile b/Makefile @@ -1,12 +1,12 @@ CFLAGS+=-Wall -Wextra -g -std=c99 -all: fzy testscore +all: fzy fzytest -testscore: testscore.o match.o +fzytest: fzytest.o match.o $(CC) $(CCFLAGS) -o $@ $^ -test: testscore - ruby test.rb +test: fzytest + -./fzytest fzy: fzy.o match.o $(CC) $(CCFLAGS) -o $@ $^ @@ -15,4 +15,6 @@ fzy: fzy.o match.o $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< clean: - $(RM) fzy testscore *.o + $(RM) fzy fzytest *.o + +.PHONY: test all clean diff --git a/fzytest.c b/fzytest.c @@ -0,0 +1,42 @@ +#include <stdio.h> +#include "fzy.h" + +const char *testname; +int testsrun = 0, testspassed = 0; + +#define TEST(name) int test_##name(){ testname = #name; testsrun++; do +#define ENDTEST while(0); testspassed++; return 0;} +#define assert(x) if(!(x)){fprintf(stderr, "test \"%s\" failed\n assert(%s) was false\n at %s:%i\n\n", testname, #x, __FILE__ ,__LINE__);return -1;} + +TEST(match){ + assert(has_match("a", "a")); + assert(has_match("a", "ab")); + assert(has_match("a", "ba")); + assert(has_match("abc", "a|b|c")); + + /* non-match */ + assert(!has_match("a", "")); + assert(!has_match("a", "b")); + + /* match when query is empty */ + assert(has_match("", "")); + assert(has_match("", "a")); +}ENDTEST + +TEST(scoring){ + assert(match("amo", "app/models/foo") < match("amo", "app/models/order")); +}ENDTEST + +void summary(){ + printf("%i tests run: %i passed %i failed\n", testsrun, testspassed, testsrun - testspassed); +} + +int main(int argc, char *argv[]){ + test_match(); + test_scoring(); + + summary(); + + /* exit 0 if all tests pass */ + return testsrun != testspassed; +} diff --git a/test.rb b/test.rb @@ -1,54 +0,0 @@ -require "minitest/autorun" - -# Largely borrowed from selecta -describe "score" do - def score(candidate, query) - # FIXME: should escape this properly - ret = `./testscore '#{query}' '#{candidate}'` - ret.to_f unless ret.empty? - end - - def assert_unmatched(candidate, query) - assert_equal nil, score(candidate, query) - end - - def assert_matched(candidate, query) - assert_operator 0, :<=, score(candidate, query) - end - - it "scores 1 when the query is empty" do - assert_equal 1, score("a", "") - end - - it "scores 0 when the choice is empty" do - assert_unmatched "", "a" - end - - it "scores 1 when exact match" do - assert_equal 1, score("a", "a") - end - - it "scores 0 when the query is longer than the choice" do - assert_unmatched "short", "longer" - end - - it "scores 0 when the query doesn't match at all" do - assert_unmatched "a", "b" - end - - it "scores 0 when only a prefix of the query matches" do - assert_unmatched "ab", "ac" - end - - it "scores greater than 0 when it matches" do - assert_matched "a", "a" - assert_matched "ab", "a" - assert_matched "ba", "a" - assert_matched "bab", "a" - assert_matched "bababababab", "aaaaa" - end - - it "prefers start of words" do - assert_operator score("app/models/foo", "amo"), :<, score("app/models/order", "amo") - end -end diff --git a/testscore.c b/testscore.c @@ -1,22 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> - -#include "fzy.h" -double match(const char *needle, const char *haystack); - -void usage(const char *argv0){ - fprintf(stderr, "USAGE: %s QUERY CANDIDATE\n", argv0); -} - -int main(int argc, char *argv[]){ - if(argc != 3){ - usage(argv[0]); - } - - if(has_match(argv[1], argv[2])){ - double result = match(argv[1], argv[2]); - printf("%f\n", result); - } - - return 0; -}