Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement a rudimentory test framework and CI #2

Merged
merged 1 commit into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Run tests
on:
- push
- pull_request

jobs:
run-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: setup ripgrep and gcc
run: |
sudo apt-get update
sudo apt install build-essential
sudo apt install ripgrep
- name: run tests
run: |
make run_test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
gsx
test/test
*.o
15 changes: 11 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,27 @@ CC = gcc
TREE_SITTER=$(CURDIR)/tree-sitter
TREE_SITTER_TSX=$(CURDIR)/tree-sitter-typescript/tsx
STATIC_LIB = $(TREE_SITTER)/libtree-sitter.a
INCLUDE=$(TREE_SITTER)/lib/include

default: gsx

$(STATIC_LIB):
cd $(TREE_SITTER) && $(MAKE)

scanner.o: $(TREE_SITTER_TSX)/src/scanner.c
$(CC) -c $< -o $@
$(CC) -c $< -o $@ -I$(INCLUDE)

parser.o: $(TREE_SITTER_TSX)/src/parser.c
$(CC) -c $< -o $@
$(CC) -c $< -o $@ -I$(INCLUDE)

gsx: src/parse.h src/parse.c src/main.c scanner.o parser.o $(STATIC_LIB)
$(CC) -Wall -Wextra -std=c11 -pedantic -o gsx $(CGLAGS) src/parse.c src/main.c scanner.o parser.o $(STATIC_LIB)
gsx: src/parse.h src/parse.c src/utils.c src/main.c scanner.o parser.o $(STATIC_LIB)
$(CC) -Wall -Wextra -std=c11 -pedantic -o gsx $(CGLAGS) src/utils.c src/parse.c src/main.c scanner.o parser.o $(STATIC_LIB) -I$(TREE_SITTER)/lib/include

test/test: gsx src/utils.c test/test.c
$(CC) -Wall -Wextra -o test/test src/utils.c test/test.c

run_test: test/test
./test/test

clean:
rm -f *.o && rm -f main
Expand Down
26 changes: 2 additions & 24 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <errno.h>

#include "parse.h"
#include "utils.h"

#define INIT_RESULT_CAPACITY 32
#define MAX_COMMAND_LINE_LENGTH 1024
Expand Down Expand Up @@ -41,29 +42,6 @@ void free_result(Result *r) {
r->size = r->capacity = 0;
}

char* readFile(char* file_name) {
FILE *f = fopen(file_name, "rb");

if (f == NULL) {
fprintf(stderr, "Couldn't open %s", file_name);
fprintf(stderr, "%d", errno);

exit(EXIT_FAILURE);
}
if(fseek(f, 0, SEEK_END) != 0) {
fprintf(stderr, "Error reading %s", file_name);
exit(EXIT_FAILURE);
}
long size = ftell(f);
char* source_code = (char *)malloc((size+1) * sizeof(char));
rewind(f);

fread(source_code, 1, size, f);
source_code[size] = '\0';
fclose(f);

return source_code;
}

char* get_node_content(TSNode node, char* source_code) {
uint32_t start_offset = ts_node_start_byte(node);
Expand Down Expand Up @@ -213,7 +191,7 @@ int main(int argc, char** argv) {

while (fgets(file_path, sizeof(file_path), cmd)) {
file_path[strlen(file_path)-1] = '\0';
char* source_code = readFile(file_path);
char* source_code = read_file(file_path);
Result result_ast = { .items = NULL, .size = 0, .capacity = 0 };

TSTree* tree = build_tree(source_code, file_path, parser, &p, &result_ast);
Expand Down
51 changes: 51 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#define _GNU_SOURCE // make popen available
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#define CHUNK_SIZE 64*100

char* read_file(char* file_name) {
FILE *f = fopen(file_name, "rb");

if (f == NULL) {
fprintf(stderr, "Couldn't open %s", file_name);
fprintf(stderr, "%d", errno);

exit(EXIT_FAILURE);
}
if (fseek(f, 0, SEEK_END) != 0) {
fprintf(stderr, "Error reading %s", file_name);
exit(EXIT_FAILURE);
}
long size = ftell(f);
char* content = (char *)malloc((size+1) * sizeof(char));
rewind(f);

fread(content, 1, size, f);
content[size] = '\0';

fclose(f);
return content;
}

char* read_command(char* command) {
char *result = (char *)malloc(CHUNK_SIZE * sizeof(char));
size_t bytes_length = 0;
size_t length = 0;

FILE *output = popen(command, "r");
if (output == NULL) {
fprintf(stderr, "Error running command: %s\n", command);
exit(EXIT_FAILURE);
}
while((bytes_length = fread(result, 1, CHUNK_SIZE, output)) > 0) {
length += bytes_length;
result = (char *)realloc(result, (length + 1) * sizeof(char));
}
result[length] = '\0';

pclose(output);
return result;

}
2 changes: 2 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
char *read_file(const char* file_path);
char *read_command(const char* command);
2 changes: 2 additions & 0 deletions test/exclude_one_prop.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
test/samples/file.tsx:8:<Button size="large">
--
2 changes: 2 additions & 0 deletions test/include_one_exclude_one.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
test/samples/file.tsx:9:<Button variant="secondary">
--
4 changes: 4 additions & 0 deletions test/one_prop.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
test/samples/file.tsx:5:<Button variant="primary" size="large">
--
test/samples/file.tsx:9:<Button variant="secondary">
--
13 changes: 13 additions & 0 deletions test/samples/file.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const Test = () => {
return (
<Box variant="primary" onClick={() => console.log("test")}>
<div>
<Button variant="primary" size="large">
Button
</Button>
<Button size="large">Button</Button>
<Button variant="secondary">Button</Button>
</div>
</Box>
);
};
6 changes: 6 additions & 0 deletions test/simple.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
test/samples/file.tsx:5:<Button variant="primary" size="large">
--
test/samples/file.tsx:8:<Button size="large">
--
test/samples/file.tsx:9:<Button variant="secondary">
--
75 changes: 75 additions & 0 deletions test/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "../src/utils.h"

typedef const char* Filepath;
typedef const char* Command;
typedef const char* Name;

typedef struct {
Name name;
Command command;
Filepath file;
} Test;


bool run_test(Test* test) {
bool success = true;
char *result = read_command(test->command);
char *expected = read_file(test->file);

if (strlen(result) > 0 && memcmp(result, expected, strlen(result)) == 0) {
printf("%s: OK\n", test->name);
} else {
printf("%s: KO\n", test->name);
printf("Expected: \n");
printf("%s\n", expected);
printf("Got: \n");
printf("%s\n", result);
success = false;
}
printf("----------------------------------------\n");
free(expected);
free(result);
return success;
}

Test tests[] = {
(Test) {
.name = "Button",
.command = "./gsx test/samples/ Button",
.file = "./test/simple.txt",
},
(Test) {
.name = "Button.^variant",
.command = "./gsx test/samples/ Button.^variant",
.file = "./test/exclude_one_prop.txt",
},
(Test) {
.name = "Button.variant",
.command = "./gsx test/samples/ Button.variant",
.file = "./test/one_prop.txt",
},
(Test) {
.name = "Button.variant,^size",
.command = "./gsx test/samples/ Button.variant,^size",
.file = "./test/include_one_exclude_one.txt",
},
};

int main(void) {
size_t nb_test = sizeof(tests) / sizeof(tests[0]);
printf("Running all tests\n\n");
int success = 0;
for (size_t i = 0; i < nb_test; ++i) {
if (!run_test(&tests[i])) {
success = 1;
}
}
return success;
}