;;; khoj-tests.el --- Test suite for khoj.el -*- lexical-binding: t -*- ;; Copyright (C) 2023 Debanjum Singh Solanky ;; Author: Debanjum Singh Solanky ;; Version: 0.0.0 ;; Package-Requires: ((emacs "27.1") (transient "0.3.0") (dash "2.19.1") (org "9.0.0")) ;; URL: https://github.com/khoj-ai/khoj/tree/master/src/interface/emacs ;;; License: ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License ;; as published by the Free Software Foundation; either version 3 ;; of the License, or (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; This file contains the test suite for khoj.el. ;;; Code: (require 'dash) (require 'ert) (require 'khoj) (require 'org) ;; ---------------------------------------------------- ;; Test Extract and Render Entries of each Content Type ;; ---------------------------------------------------- (ert-deftest khoj-tests--extract-entries-as-markdown () "Test `json-response', `query' from API formatted as markdown." (let ((user-query "Become God") (json-response-from-khoj-backend (json-read-from-string "[\ {\ \"entry\": \"## Upgrade\\n\\n Penance to Immortality\",\ \"score\": \"0.376\",\ \"additional\": {\ \"file\": \"/home/ravan/upgrade.md\",\ \"compiled\": \"## Upgrade Penance to Immortality\"\ }\ },\ {\ \"entry\": \"## Act\\n\\n Rule everything\",\ \"score\": \"0.153\",\ \"additional\": {\ \"file\": \"/home/ravan/act.md\",\ \"compiled\": \"## Act Rule everything\"\ }\ }]\ "))) (should (equal (khoj--extract-entries-as-markdown json-response-from-khoj-backend user-query nil) "\ # Become God\n\ ## Upgrade\n\ \n\ Penance to Immortality\n\n\ ## Act\n\ \n\ Rule everything\n\n")))) (ert-deftest khoj-tests--extract-entries-as-org () "Test `json-response', `query' from API formatted as org." (let ((user-query "Become God") (json-response-from-khoj-backend (json-read-from-string "[\ {\ \"entry\": \"** Upgrade\\n\\n Penance to Immortality\\n\",\ \"score\": \"0.42\",\ \"additional\": {\ \"file\": \"/home/ravan/upgrade.md\",\ \"compiled\": \"** Upgrade Penance to Immortality\"\ }\ },\ {\ \"entry\": \"** Act\\n\\n Rule everything\\n\",\ \"score\": \"0.42\",\ \"additional\": {\ \"file\": \"/home/ravan/act.md\",\ \"compiled\": \"** Act Rule everything\"\ }\ }]\ "))) (should (equal (khoj--extract-entries-as-org json-response-from-khoj-backend user-query nil) "\ * Become God\n\ ** Upgrade\n\ \n\ Penance to Immortality\n\ ** Act\n\ \n\ Rule everything\n\ \n")))) ;; ------------------------------------- ;; Test Helpers for Find Similar Feature ;; ------------------------------------- (ert-deftest khoj-tests--get-current-outline-entry-text () "Test get current outline-mode entry text'." (with-temp-buffer (insert "\ * Become God\n\ ** Upgrade\n\ \n\ Penance to Immortality\n\ ** Act\n\ \n\ Rule everything\\n") (goto-char (point-min)) ;; Test getting current entry text from cursor at start of outline heading (outline-next-visible-heading 1) (should (equal (khoj--get-current-outline-entry-text) "\ ** Upgrade\n\ \n\ Penance to Immortality")) ;; Test getting current entry text from cursor within outline entry (forward-line) (should (equal (khoj--get-current-outline-entry-text) "\ ** Upgrade\n\ \n\ Penance to Immortality")) )) (ert-deftest khoj-tests--get-current-paragraph-text () "Test get current paragraph text'." (with-temp-buffer (insert "\ * Become God\n\ ** Upgrade\n\ \n\ Penance to Immortality\n\ ** Act\n\ \n\ Rule everything\n") ;; Test getting current paragraph text from cursor at start of buffer (goto-char (point-min)) (should (equal (khoj--get-current-paragraph-text) "* Become God\n\ ** Upgrade")) ;; Test getting current paragraph text from cursor within paragraph (goto-char (point-min)) (forward-line 1) (should (equal (khoj--get-current-paragraph-text) "* Become God\n\ ** Upgrade")) ;; Test getting current paragraph text from cursor at paragraph end (goto-char (point-min)) (forward-line 2) (should (equal (khoj--get-current-paragraph-text) "* Become God\n\ ** Upgrade")) ;; Test getting current paragraph text from cursor at start of middle paragraph (goto-char (point-min)) (forward-line 3) (should (equal (khoj--get-current-paragraph-text) "Penance to Immortality\n\ ** Act")) ;; Test getting current paragraph text from cursor at end of buffer (goto-char (point-max)) (should (equal (khoj--get-current-paragraph-text) "Rule everything")) )) ;; ------------------------------------- ;; Test Helpers to Index Content ;; ------------------------------------- (ert-deftest khoj-tests--render-files-to-add-request-body () "Test files are formatted into a multi-part http request body" (let ((upgrade-file (make-temp-file "upgrade" nil ".org" "# Become God\n## Upgrade\n\nPenance to Immortality\n\n")) (act-file (make-temp-file "act" nil ".org" "## Act\n\nRule everything\n\n"))) (unwind-protect (progn (should (equal (khoj--render-update-files-as-request-body (list upgrade-file act-file) "khoj") (format "\n--khoj\r\n\ Content-Disposition: form-data; name=\"files\"; filename=\"%s\"\r\n\ Content-Type: text/org\r\n\r\n\ # Become God\n\ ## Upgrade\n\n\ Penance to Immortality\n\n\r --khoj\r\n\ Content-Disposition: form-data; name=\"files\"; filename=\"%s\"\r\n\ Content-Type: text/org\r\n\r\n\ ## Act\n\n\ Rule everything\n\n\r\n\ --khoj--\r\n" upgrade-file act-file)))) (delete-file upgrade-file) (delete-file act-file)))) (ert-deftest khoj-tests--render-files-to-add-delete-in-request-body () "Test files are formatted into a multi-part http request body" (let ((upgrade-file (make-temp-file "upgrade" nil ".org" "# Become God\n## Upgrade\n\nPenance to Immortality\n\n")) (act-file (make-temp-file "act" nil ".org" "## Act\n\nRule everything\n\n"))) (unwind-protect (progn (should (equal (khoj--render-delete-files-as-request-body (list upgrade-file act-file "/tmp/deleted-file.org") "khoj") (format "\n--khoj\r\n\ Content-Disposition: form-data; name=\"files\"; filename=\"%s\"\r\n\ Content-Type: text/org\r\n\r\n\ \r --khoj\r\n\ Content-Disposition: form-data; name=\"files\"; filename=\"%s\"\r\n\ Content-Type: text/org\r\n\r\n\ \r --khoj\r\n\ Content-Disposition: form-data; name=\"files\"; filename=\"%s\"\r\n\ Content-Type: text/org\r\n\r\n\ \r --khoj--\r\n" upgrade-file act-file "/tmp/deleted-file.org")))) (delete-file upgrade-file) (delete-file act-file)))) (ert-deftest khoj-tests--extract-online-references () (let* (;; Arrange (onlineContext '((Albert\ Einstein\ wife (organic . [((link . "https://en.wikipedia.org/wiki/Mileva_Mari%C4%87") (title . "Mileva Marić - Wikipedia") (snippet . "Marić married Einstein in 1903 and they had three ...") (position . 1) (sitelinks . [((link . "https://en.wikipedia.org/wiki/Mileva_Mari%C4%87#Bi...") (title . "Biography")) ((link . "https://en.wikipedia.org/wiki/Mileva_Mari%C4%87#De...") (title . "Debate over collaboration with..."))])) ((link . "https://en.wikipedia.org/wiki/Elsa_Einstein") (title . "Elsa Einstein - Wikipedia") (snippet . "Elsa Einstein (18 January 1876 – 20 December 1936)...") (position . 2)) ((link . "https://www.amazon.com/Einsteins-Wife-Story-Mileva...") (price . 25.86) (title . "Einstein's Wife: The Real Story of Mileva Einstein...") (rating . 3.8) (snippet . "Albert Einstein's first wife, Mileva Einstein-Mari...") (currency . "$") (position . 3) (ratingCount . 80))]) (peopleAlsoAsk . [((link . "https://en.wikipedia.org/wiki/Mileva_Mari%C4%87") (title . "Mileva Marić - Wikipedia") (snippet . "Death. Mileva Marić suffered a severe stroke and d...") (question . "What happened to Einstein's first wife?")) ((link . "https://www.redalyc.org/journal/5117/511767145014/...") (title . "The story of Mileva Marić: Did Einstein's first wi...") (snippet . "The couple were married in 1903. Some claim that M...") (question . "Did Albert Einstein's wife do all his work?")) ((link . "https://en.wikipedia.org/wiki/Hans_Albert_Einstein") (title . "Hans Albert Einstein - Wikipedia") (snippet . "Klaus Martin Einstein (1932–1939), died of diphthe...") (question . "What happened to Einstein's children?"))]) (knowledgeGraph (type . "Theoretical physicist") (title . "Albert Einstein") (attributes (Born . "March 14, 1879, Ulm, Germany") (Died . "April 18, 1955 (age 76 years), Princeton, NJ") (Spouse . "Elsa Einstein (m. 1919–1936) and Mileva Marić (m. ...") (Children . "Eduard Einstein, Hans Albert Einstein, and Lieserl...") (Education . "University of Zurich (1905), ETH Zürich (1897–1900...") (Nationality . "American, German, Hungarian, and more") (Grandchildren . "Evelyn Einstein, Bernhard Caesar Einstein, Klaus M...")) (description . "Albert Einstein was a German-born theoretical phys...") (descriptionLink . "https://en.wikipedia.org/wiki/Albert_Einstein") (descriptionSource . "Wikipedia"))) (Prince\ Albert\ spouse (webpages (link . "https://en.wikipedia.org/wiki/Prince_Albert_of_Sax...") (snippet . "Prince Albert of Saxe-Coburg and Gotha was the hus...")) (organic . [((date . "Feb 4, 2024") (link . "https://en.wikipedia.org/wiki/Prince_Albert_of_Sax...") (title . "Prince Albert of Saxe-Coburg and Gotha - Wikipedia") (snippet . "Prince Albert of Saxe-Coburg and Gotha was the hus...") (position . 1) (sitelinks . [((link . "https://en.wikipedia.org/wiki/Prince_consort") (title . "Prince consort")) ((link . "https://en.wikipedia.org/wiki/Nellie_Clifden") (title . "Nellie Clifden"))]))]) (answerBox (title . "Prince Albert of Saxe-Coburg and Gotha / Spouse") (answer . "Queen Victoria")) (peopleAlsoAsk . [((link . "https://en.wikipedia.org/wiki/Albert_II,_Prince_of...") (title . "Albert II, Prince of Monaco - Wikipedia") (snippet . "In July 2011, Prince Albert married South African ...") (question . "How many children does Prince Albert of Monaco hav..."))])))) ;; Act (result (khoj--extract-online-references '(organic knowledgeGraph peopleAlsoAsk webpages) onlineContext))) ;; Assert (progn (should (equal (length result) 10)) result))) (provide 'khoj-tests) ;;; khoj-tests.el ends here