diff --git a/package-lock.json b/package-lock.json index 2aca0d8..41928df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "language-detector", "version": "1.0.6", "license": "MIT", "devDependencies": { @@ -21,7 +22,8 @@ "prettier": "^2.3.2", "rollup": "^2.56.1", "typescript": "^4.3.5", - "uvu": "^0.5.1" + "uvu": "^0.5.1", + "watchlist": "^0.2.3" } }, "node_modules/@babel/code-frame": { @@ -2297,6 +2299,21 @@ "node": ">=10.12.0" } }, + "node_modules/watchlist": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/watchlist/-/watchlist-0.2.3.tgz", + "integrity": "sha512-xStuPg489QXZbRirnmIMo7OaKFnGkvTQn7tCUC/sVmVVEvDQQnnVl/k9D5yg3nXgpebgPHpfApBLHMpEbAqvSQ==", + "dev": true, + "dependencies": { + "mri": "^1.1.5" + }, + "bin": { + "watchlist": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4043,6 +4060,15 @@ "source-map": "^0.7.3" } }, + "watchlist": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/watchlist/-/watchlist-0.2.3.tgz", + "integrity": "sha512-xStuPg489QXZbRirnmIMo7OaKFnGkvTQn7tCUC/sVmVVEvDQQnnVl/k9D5yg3nXgpebgPHpfApBLHMpEbAqvSQ==", + "dev": true, + "requires": { + "mri": "^1.1.5" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index ead7d68..e2b144d 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,10 @@ "lint": "eslint --fix --ignore-path .gitignore .", "format": "prettier --write --ignore-path .gitignore .", "prepare": "node prepare.cjs", - "test": "c8 uvu -r esbuild-register tests \".(test|spec).ts\"", + "test:unit": "uvu -r esbuild-register tests \".(test|spec).ts\"", + "test:coverage": "c8 npm run test:unit", + "test:tdd": "npm run test:unit; watchlist src/ -- npm run test:unit", + "test": "npm run test:coverage", "build": "rollup -c" }, "files": [ @@ -59,6 +62,7 @@ "prettier": "^2.3.2", "rollup": "^2.56.1", "typescript": "^4.3.5", - "uvu": "^0.5.1" + "uvu": "^0.5.1", + "watchlist": "^0.2.3" } } diff --git a/tests/c.test.ts b/tests/c.test.ts index a50c931..0cf8732 100644 --- a/tests/c.test.ts +++ b/tests/c.test.ts @@ -3,13 +3,12 @@ import * as assert from 'uvu/assert'; import detectLang from '../src/index'; test('hello world', () => { - assert.equal('C', detectLang('printf("Hello world!\\n");')); + const code = detectLang('printf("Hello world!\\n");'); + assert.equal(code, 'C'); }); test('fizz buzz', () => { - assert.equal( - 'C', - detectLang(`#include + const code = detectLang(`#include int main(void) { @@ -30,18 +29,17 @@ test('fizz buzz', () => { } return 0; - }`), - ); + }`); + assert.equal(code, 'C'); }); test('variable declaration', () => { - assert.equal('C', detectLang('int *ptr;')); + const code = detectLang('int *ptr;'); + assert.equal(code, 'C'); }); test('file', () => { - assert.equal( - 'C', - detectLang(`static int IndexEntry__set_mtime__meth(lua_State *L) { + const code = detectLang(`static int IndexEntry__set_mtime__meth(lua_State *L) { IndexEntry * this_idx1 = obj_type_IndexEntry_check(L,1); git_time_t secs_idx2 = luaL_checkinteger(L,2); unsigned int nanosecs_idx3 = luaL_checkinteger(L,3); @@ -49,8 +47,82 @@ test('file', () => { this_idx1->mtime.nanoseconds = nanosecs_idx3; return 0; - }`), - ); + }`); + assert.equal(code, 'C'); +}); + +test('quick sort', () => { + const code = detectLang(`#include + + void quicksort(int *A, int len); + + int main (void) { + int a[] = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1}; + int n = sizeof a / sizeof a[0]; + + int i; + for (i = 0; i < n; i++) { + printf("%d ", a[i]); + } + printf("\n"); + + quicksort(a, n); + + for (i = 0; i < n; i++) { + printf("%d ", a[i]); + } + printf("\n"); + + return 0; + } + + void quicksort(int *A, int len) { + if (len < 2) return; + + int pivot = A[len / 2]; + + int i, j; + for (i = 0, j = len - 1; ; i++, j--) { + while (A[i] < pivot) i++; + while (A[j] > pivot) j--; + + if (i >= j) break; + + int temp = A[i]; + A[i] = A[j]; + A[j] = temp; + } + + quicksort(A, i); + quicksort(A + i, len - i); + }`); + assert.equal(code, 'C'); +}); + +test('http server', () => { + const code = detectLang(`#include + #include + #include + + int + main(void) + { + CURL *curl; + char buffer[CURL_ERROR_SIZE]; + + if ((curl = curl_easy_init()) != NULL) { + curl_easy_setopt(curl, CURLOPT_URL, "http://www.rosettacode.org/"); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, buffer); + if (curl_easy_perform(curl) != CURLE_OK) { + fprintf(stderr, "%s\n", buffer); + return EXIT_FAILURE; + } + curl_easy_cleanup(curl); + } + return EXIT_SUCCESS; + }`); + assert.equal(code, 'C'); }); test.run(); diff --git a/tests/cpp.test.ts b/tests/cpp.test.ts index a52f5df..549a2f6 100644 --- a/tests/cpp.test.ts +++ b/tests/cpp.test.ts @@ -3,13 +3,12 @@ import * as assert from 'uvu/assert'; import detectLang from '../src/index'; test('hello world', () => { - assert.equal('C++', detectLang('cout << "Hello world" << endl;')); + const code = detectLang('cout << "Hello world" << endl;'); + assert.equal(code, 'C++'); }); test('fizz buzz', () => { - assert.equal( - 'C++', - detectLang(`/* + const code = detectLang(`/* * fizzbuzz.cpp * * Created on: Apr 25, 2012 @@ -49,8 +48,149 @@ test('fizz buzz', () => { { FizzBuzz<100> p; return 0; - }`), - ); + }`); + assert.equal(code, 'C++'); +}); + +test('quick sort', () => { + const code = detectLang(`#include + #include // for std::partition + #include // for std::less + + // helper function for median of three + template + T median(T t1, T t2, T t3) + { + if (t1 < t2) + { + if (t2 < t3) + return t2; + else if (t1 < t3) + return t3; + else + return t1; + } + else + { + if (t1 < t3) + return t1; + else if (t2 < t3) + return t3; + else + return t2; + } + } + + // helper object to get <= from < + template struct non_strict_op: + public std::binary_function + { + non_strict_op(Order o): order(o) {} + bool operator()(typename Order::second_argument_type arg1, + typename Order::first_argument_type arg2) const + { + return !order(arg2, arg1); + } + private: + Order order; + }; + + template non_strict_op non_strict(Order o) + { + return non_strict_op(o); + } + + template + void quicksort(RandomAccessIterator first, RandomAccessIterator last, Order order) + { + if (first != last && first+1 != last) + { + typedef typename std::iterator_traits::value_type value_type; + RandomAccessIterator mid = first + (last - first)/2; + value_type pivot = median(*first, *mid, *(last-1)); + RandomAccessIterator split1 = std::partition(first, last, std::bind2nd(order, pivot)); + RandomAccessIterator split2 = std::partition(split1, last, std::bind2nd(non_strict(order), pivot)); + quicksort(first, split1, order); + quicksort(split2, last, order); + } + } + + template + void quicksort(RandomAccessIterator first, RandomAccessIterator last) + { + quicksort(first, last, std::less::value_type>()); + } + A simpler version of the above that just uses the first element as the pivot and only does one "partition". + + #include + #include // for std::partition + #include // for std::less + + template + void quicksort(RandomAccessIterator first, RandomAccessIterator last, Order order) + { + if (last - first > 1) + { + RandomAccessIterator split = std::partition(first+1, last, std::bind2nd(order, *first)); + std::iter_swap(first, split-1); + quicksort(first, split-1, order); + quicksort(split, last, order); + } + } + + template + void quicksort(RandomAccessIterator first, RandomAccessIterator last) + { + quicksort(first, last, std::less::value_type>()); + }`); + assert.equal(code, 'C++'); +}); + +// FIXME: This detected as C. +test.skip('http server', () => { + const code = detectLang(`#include + #include + #include + + int main() { + WSADATA wsaData; + WSAStartup( MAKEWORD( 2, 2 ), &wsaData ); + + addrinfo *result = NULL; + addrinfo hints; + + ZeroMemory( &hints, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + getaddrinfo( "74.125.45.100", "80", &hints, &result ); // http://www.google.com + + SOCKET s = socket( result->ai_family, result->ai_socktype, result->ai_protocol ); + + connect( s, result->ai_addr, (int)result->ai_addrlen ); + + freeaddrinfo( result ); + + send( s, "GET / HTTP/1.0\n\n", 16, 0 ); + + char buffer[512]; + int bytes; + + do { + bytes = recv( s, buffer, 512, 0 ); + + if ( bytes > 0 ) + std::cout.write(buffer, bytes); + } while ( bytes > 0 ); + + return 0; + }`); + assert.equal(code, 'C++'); }); test.run(); diff --git a/tests/css.test.ts b/tests/css.test.ts index 8784132..35b2e11 100644 --- a/tests/css.test.ts +++ b/tests/css.test.ts @@ -3,13 +3,12 @@ import * as assert from 'uvu/assert'; import detectLang from '../src/index'; test('hello world', () => { - assert.equal('CSS', detectLang('.hello-world {\n\tfont-size: 100px;\n}')); + const code = detectLang('.hello-world {\n\tfont-size: 100px;\n}'); + assert.equal(code, 'CSS'); }); test('long', () => { - assert.equal( - 'CSS', - detectLang(`/** + const code = detectLang(`/** * Improve readability when focused and also mouse hovered in all browsers. */ @@ -24,8 +23,8 @@ test('long', () => { abbr[title] { border-bottom: 1px dotted; - }`), - ); + }`); + assert.equal(code, 'CSS'); }); test.run(); diff --git a/tests/go.test.ts b/tests/go.test.ts index 94f0ac5..19e1de1 100644 --- a/tests/go.test.ts +++ b/tests/go.test.ts @@ -3,43 +3,159 @@ import * as assert from 'uvu/assert'; import detectLang from '../src/index'; test('hello world', () => { - assert.equal('Go', detectLang('fmt.Println("Hello world")')); + const code = detectLang('fmt.Println("Hello world")'); + assert.equal(code, 'Go'); }); test('fizz buzz', () => { - assert.equal( - 'Go', - detectLang(`package main + const code = detectLang(`package main -import ( - "fmt" - "flag" -) - -var max *int = flag.Int("max", 0, "enter integer or bust!") - -func main() { - flag.Parse() - for i := 1; i <= *max; i++ { - fizzbuzz(i) + import ( + "fmt" + "flag" + ) + + var max *int = flag.Int("max", 0, "enter integer or bust!") + + func main() { + flag.Parse() + for i := 1; i <= *max; i++ { + fizzbuzz(i) + } } -} + + func fizzbuzz(i int) { + fizz := "fizz" + buzz := "buzz" + + if i % 3 == 0 && i % 5 == 0 { + fmt.Println(i, fizz + buzz) + } else if i % 3 == 0 { + fmt.Println(i, fizz) + } else if i % 5 == 0 { + fmt.Println(i, buzz) + } else { + fmt.Println(i) + } + }`); + assert.equal(code, 'Go'); +}); + +test('quick sort', () => { + const code = detectLang(`package main -func fizzbuzz(i int) { - fizz := "fizz" - buzz := "buzz" - - if i % 3 == 0 && i % 5 == 0 { - fmt.Println(i, fizz + buzz) - } else if i % 3 == 0 { - fmt.Println(i, fizz) - } else if i % 5 == 0 { - fmt.Println(i, buzz) - } else { - fmt.Println(i) + import "fmt" + + func main() { + list := []int{31, 41, 59, 26, 53, 58, 97, 93, 23, 84} + fmt.Println("unsorted:", list) + + quicksort(list) + fmt.Println("sorted! ", list) } -}`), - ); + + func quicksort(a []int) { + var pex func(int, int) + pex = func(lower, upper int) { + for { + switch upper - lower { + case -1, 0: // 0 or 1 item in segment. nothing to do here! + return + case 1: // 2 items in segment + // < operator respects strict weak order + if a[upper] < a[lower] { + // a quick exchange and we're done. + a[upper], a[lower] = a[lower], a[upper] + } + return + // Hoare suggests optimized sort-3 or sort-4 algorithms here, + // but does not provide an algorithm. + } + + // Hoare stresses picking a bound in a way to avoid worst case + // behavior, but offers no suggestions other than picking a + // random element. A function call to get a random number is + // relatively expensive, so the method used here is to simply + // choose the middle element. This at least avoids worst case + // behavior for the obvious common case of an already sorted list. + bx := (upper + lower) / 2 + b := a[bx] // b = Hoare's "bound" (aka "pivot") + lp := lower // lp = Hoare's "lower pointer" + up := upper // up = Hoare's "upper pointer" + outer: + for { + // use < operator to respect strict weak order + for lp < upper && !(b < a[lp]) { + lp++ + } + for { + if lp > up { + // "pointers crossed!" + break outer + } + // < operator for strict weak order + if a[up] < b { + break // inner + } + up-- + } + // exchange + a[lp], a[up] = a[up], a[lp] + lp++ + up-- + } + // segment boundary is between up and lp, but lp-up might be + // 1 or 2, so just call segment boundary between lp-1 and lp. + if bx < lp { + // bound was in lower segment + if bx < lp-1 { + // exchange bx with lp-1 + a[bx], a[lp-1] = a[lp-1], b + } + up = lp - 2 + } else { + // bound was in upper segment + if bx > lp { + // exchange + a[bx], a[lp] = a[lp], b + } + up = lp - 1 + lp++ + } + // "postpone the larger of the two segments" = recurse on + // the smaller segment, then iterate on the remaining one. + if up-lower < upper-lp { + pex(lower, up) + lower = lp + } else { + pex(lp, upper) + upper = up + } + } + } + pex(0, len(a)-1) + }`); + assert.equal(code, 'Go'); +}); + +test('http server', () => { + const code = detectLang(`package main + + import ( + "io" + "log" + "net/http" + "os" + ) + + func main() { + r, err := http.Get("http://rosettacode.org/robots.txt") + if err != nil { + log.Fatalln(err) + } + io.Copy(os.Stdout, r.Body) + }`); + assert.equal(code, 'Go'); }); test.run(); diff --git a/tests/html.test.ts b/tests/html.test.ts index a99f861..8b38b0d 100644 --- a/tests/html.test.ts +++ b/tests/html.test.ts @@ -3,13 +3,12 @@ import * as assert from 'uvu/assert'; import detectLang from '../src/index'; test('hello world', () => { - assert.equal('HTML', detectLang('

Hello world

')); + const code = detectLang('

Hello world

'); + assert.equal(code, 'HTML'); }); test('page', () => { - assert.equal( - 'HTML', - detectLang(` + const code = detectLang(` Page Title @@ -19,8 +18,8 @@ test('page', () => {

This is a tiny HTML page.

- `), - ); + `); + assert.equal(code, 'HTML'); }); test.run(); diff --git a/tests/java.test.ts b/tests/java.test.ts index ad84130..8ee7853 100644 --- a/tests/java.test.ts +++ b/tests/java.test.ts @@ -3,13 +3,12 @@ import * as assert from 'uvu/assert'; import detectLang from '../src/index'; test('hello world', () => { - assert.equal('Java', detectLang('System.out.println("Hello world!");')); + const code = detectLang('System.out.println("Hello world!");'); + assert.equal(code, 'Java'); }); test('fizz buzz', () => { - assert.equal( - 'Java', - detectLang(`public class FizzBuzz { + const code = detectLang(`public class FizzBuzz { public static void main(String[] args) { for(int i = 1; i <= 100; i++) { if (((i % 5) == 0) && ((i % 7) == 0)) @@ -21,16 +20,76 @@ test('fizz buzz', () => { } System.out.println(); } - }`), - ); + }`); + assert.equal(code, 'Java'); }); test('getter/setter', () => { - assert.equal('Java', detectLang('Person person = people.get(0);')); + const code = detectLang('Person person = people.get(0);'); + assert.equal(code, 'Java'); }); test('List/ArrayList', () => { - assert.equal('Java', detectLang('List things = new ArrayList<>();')); + const code = detectLang('List things = new ArrayList<>();'); + assert.equal(code, 'Java'); +}); + +test('quick sort', () => { + const code = detectLang(`public static > List quickSort(List arr) { + if (arr.isEmpty()) + return arr; + else { + E pivot = arr.get(0); + + List less = new LinkedList(); + List pivotList = new LinkedList(); + List more = new LinkedList(); + + // Partition + for (E i: arr) { + if (i.compareTo(pivot) < 0) + less.add(i); + else if (i.compareTo(pivot) > 0) + more.add(i); + else + pivotList.add(i); + } + + // Recursively sort sublists + less = quickSort(less); + more = quickSort(more); + + // Concatenate results + less.addAll(pivotList); + less.addAll(more); + return less; + } +} + `); + assert.equal(code, 'Java'); +}); + +test('http server', () => { + const code = detectLang(`import java.net.URI; + import java.net.http.HttpClient; + import java.net.http.HttpRequest; + import java.net.http.HttpResponse; + import java.nio.charset.Charset; + + public class Main { + public static void main(String[] args) { + var request = HttpRequest.newBuilder(URI.create("https://www.rosettacode.org")) + .GET() + .build(); + + HttpClient.newHttpClient() + .sendAsync(request, HttpResponse.BodyHandlers.ofString(Charset.defaultCharset())) + .thenApply(HttpResponse::body) + .thenAccept(System.out::println) + .join(); + } + }`); + assert.equal(code, 'Java'); }); test.run(); diff --git a/tests/javascript.test.ts b/tests/javascript.test.ts index 3ff59e0..414d4b1 100644 --- a/tests/javascript.test.ts +++ b/tests/javascript.test.ts @@ -3,21 +3,86 @@ import * as assert from 'uvu/assert'; import detectLang from '../src/index'; test('hello world', () => { - assert.equal('Javascript', detectLang('console.log("Hello world!");')); + const code = detectLang('console.log("Hello world!");'); + assert.equal(code, 'Javascript'); }); test('fizz buzz', () => { - assert.equal( - 'Javascript', - detectLang(`console.log( + const code = detectLang(`console.log( Array.apply(null, { length: 100 }) .map(Number.call, Number) .map(function (n) { return n % 15 === 0 ? 'FizzBuzz' : n % 3 === 0 ? 'Fizz' : n % 5 === 0 ? 'Buzz' : n; }), ); - `), - ); + `); + assert.equal(code, 'Javascript'); +}); + +test('quick sort', () => { + const code = detectLang(`function sort(array, less) { + + function swap(i, j) { + var t = array[i]; + array[i] = array[j]; + array[j] = t; + } + + function quicksort(left, right) { + + if (left < right) { + var pivot = array[left + Math.floor((right - left) / 2)], + left_new = left, + right_new = right; + + do { + while (less(array[left_new], pivot)) { + left_new += 1; + } + while (less(pivot, array[right_new])) { + right_new -= 1; + } + if (left_new <= right_new) { + swap(left_new, right_new); + left_new += 1; + right_new -= 1; + } + } while (left_new <= right_new); + + quicksort(left, right_new); + quicksort(left_new, right); + + } + } + + quicksort(0, array.length - 1); + + return array; + }`); + assert.equal(code, 'Javascript'); +}); + +test('http server', () => { + const code = detectLang(`const http = require('http'); + + http.get('http://rosettacode.org', (resp) => { + + let data = ''; + + // A chunk of data has been recieved. + resp.on('data', (chunk) => { + data += chunk; + }); + + // The whole response has been received. Print out the result. + resp.on('end', () => { + console.log("Data:", data); + }); + + }).on("error", (err) => { + console.log("Error: " + err.message); + });`); + assert.equal(code, 'Javascript'); }); test.run(); diff --git a/tests/php.test.ts b/tests/php.test.ts index 2df80e8..0be2daf 100644 --- a/tests/php.test.ts +++ b/tests/php.test.ts @@ -3,13 +3,12 @@ import * as assert from 'uvu/assert'; import detectLang from '../src/index'; test('hello world', () => { - assert.equal('PHP', detectLang('echo "Hello world";')); + const code = detectLang('echo "Hello world";'); + assert.equal(code, 'PHP'); }); test('fizz buzz', () => { - assert.equal( - 'PHP', - detectLang(` { } echo "\n"; - }`), - ); + }`); + assert.equal(code, 'PHP'); +}); + +test('quick sort', () => { + const code = detectLang(`function quicksort($arr){ + $lte = $gt = array(); + if(count($arr) < 2){ + return $arr; + } + $pivot_key = key($arr); + $pivot = array_shift($arr); + foreach($arr as $val){ + if($val <= $pivot){ + $lte[] = $val; + } else { + $gt[] = $val; + } + } + return array_merge(quicksort($lte),array($pivot_key=>$pivot),quicksort($gt)); + } + + $arr = array(1, 3, 5, 7, 9, 8, 6, 4, 2); + $arr = quicksort($arr); + echo implode(',',$arr);`); + assert.equal(code, 'PHP'); }); test.run(); diff --git a/tests/python.test.ts b/tests/python.test.ts index 92223db..1b0be63 100644 --- a/tests/python.test.ts +++ b/tests/python.test.ts @@ -3,13 +3,12 @@ import * as assert from 'uvu/assert'; import detectLang from '../src/index'; test('hello world', () => { - assert.equal('Python', detectLang('print "Hello world!"')); + const code = detectLang('print "Hello world!"'); + assert.equal(code, 'Python'); }); test('fizz buzz', () => { - assert.equal( - 'Python', - detectLang(`def fizzbuzz(n): + const code = detectLang(`def fizzbuzz(n): if n % 3 == 0 and n % 5 == 0: return 'FizzBuzz' @@ -22,12 +21,49 @@ test('fizz buzz', () => { else: return str(n) -print "\n".join(fizzbuzz(n) for n in xrange(0, 100))`), - ); +print "\n".join(fizzbuzz(n) for n in xrange(0, 100))`); + assert.equal(code, 'Python'); }); test('variable declaration', () => { - assert.equal('Python', detectLang('i = 1')); + const code = detectLang('i = 1'); + assert.equal(code, 'Python'); +}); + +test('quick sort', () => { + const code = detectLang(`def quickSort(arr): + less = [] + pivotList = [] + more = [] + if len(arr) <= 1: + return arr + else: + pivot = arr[0] + for i in arr: + if i < pivot: + less.append(i) + elif i > pivot: + more.append(i) + else: + pivotList.append(i) + less = quickSort(less) + more = quickSort(more) + return less + pivotList + more + +a = [4, 65, 2, -31, 0, 99, 83, 782, 1] +a = quickSort(a)`); + assert.equal(code, 'Python'); +}); + +test('http server', () => { + const code = detectLang(`from http.client import HTTPConnection + conn = HTTPConnection("example.com") + # If you need to use set_tunnel, do so here. + conn.request("GET", "/") + # Alternatively, you can use connect(), followed by the putrequest, putheader and endheaders functions. + result = conn.getresponse() + r1 = result.read() # This retrieves the entire contents. `); + assert.equal(code, 'Python'); }); test.run(); diff --git a/tests/ruby.test.ts b/tests/ruby.test.ts index a295f00..611eda1 100644 --- a/tests/ruby.test.ts +++ b/tests/ruby.test.ts @@ -3,13 +3,12 @@ import * as assert from 'uvu/assert'; import detectLang from '../src/index'; test('hello world', () => { - assert.equal('Ruby', detectLang('puts "Hello world"')); + const code = detectLang('puts "Hello world"'); + assert.equal(code, 'Ruby'); }); test('fizz buzz', () => { - assert.equal( - 'Ruby', - detectLang(`1.step(100,1) do |i| + const code = detectLang(`1.step(100,1) do |i| if (i % 5) == 0 && (i % 3) ==0 puts 'FizzBuzz' elsif (i % 5) == 0 @@ -19,8 +18,30 @@ test('fizz buzz', () => { else puts i end -end`), - ); +end`); + assert.equal(code, 'Ruby'); +}); + +// FIXME: This detects as Java. It should be Ruby. +test.skip('quick sort', () => { + const code = detectLang(`class Array + def quick_sort + return self if length <= 1 + pivot = self[0] + less, greatereq = self[1..-1].partition { |x| x < pivot } + less.quick_sort + [pivot] + greatereq.quick_sort + end +end`); + assert.equal(code, 'Ruby'); +}); + +// FIXME: This detected as PHP +test.skip('http server', () => { + const code = detectLang(`require 'fileutils' + require 'open-uri' + + open("http://rosettacode.org/") {|f| FileUtils.copy_stream(f, $stdout)}`); + assert.equal(code, 'Ruby'); }); test.run(); diff --git a/tests/unknown.test.ts b/tests/unknown.test.ts index 261a164..5e095a5 100644 --- a/tests/unknown.test.ts +++ b/tests/unknown.test.ts @@ -3,11 +3,11 @@ import * as assert from 'uvu/assert'; import detectLang from '../src/index'; test('should detect Unknown', () => { - assert.equal('Unknown', detectLang('Hello world!')); + assert.equal(detectLang('Hello world!'), 'Unknown'); }); test('should detect Unknown', () => { - assert.equal('Unknown', detectLang('ooga booga')); + assert.equal(detectLang('ooga booga'), 'Unknown'); }); test.run();