aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--.travis.yml10
-rw-r--r--Cask1
-rw-r--r--README.org3
-rw-r--r--stack-core.el171
-rw-r--r--stack-filter.el62
-rw-r--r--stack-question.el5
-rw-r--r--test/data-samples/questions.el517
-rw-r--r--test/data-samples/sites.el711
-rw-r--r--test/tests.el97
-rw-r--r--tests.el21
11 files changed, 1520 insertions, 81 deletions
diff --git a/.gitignore b/.gitignore
index 4acb5ef..2585bf5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,6 @@
# Compiled Elisp
*.elc
/.cask/
+.dir-locals.el
+/.stackmode/
+/url/
diff --git a/.travis.yml b/.travis.yml
index 595adc2..63f0cb6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -21,4 +21,12 @@ before_install:
- cask --version
script:
- - emacs -batch -L . -l ert -l tests.el -f ert-run-tests-batch-and-exit
+ - emacs --batch -L . -l ert -l test/tests.el -f ert-run-tests-batch-and-exit
+
+notifications:
+ webhooks:
+ urls:
+ - https://webhooks.gitter.im/e/07063bd143e35f54b1e8
+ on_success: change # options: [always|never|change] default: always
+ on_failure: always # options: [always|never|change] default: always
+ on_start: false # default: false
diff --git a/Cask b/Cask
index a715b2a..f5be811 100644
--- a/Cask
+++ b/Cask
@@ -6,6 +6,7 @@
(files "stack-*.el")
(depends-on "json" "1.4")
+(depends-on "url")
(development
(depends-on "ert"))
diff --git a/README.org b/README.org
index 98dffb8..da1846c 100644
--- a/README.org
+++ b/README.org
@@ -2,7 +2,8 @@
#+Author: Sean Allred
#+Date: [2014-10-30 Thu]
-[[https://travis-ci.org/vermiculus/stack-mode][https://travis-ci.org/vermiculus/stack-mode.svg]]
+[[https://travis-ci.org/vermiculus/stack-mode][https://travis-ci.org/vermiculus/stack-mode.svg?branch=master]]
+[[https://gitter.im/vermiculus/stack-mode?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge][https://badges.gitter.im/Join Chat.svg]]
=stack-mode= hopes to be a fully-featured Stack Exchange mode for
Emacs 24+ using version 2.2 (and subsequent versions as available) of
diff --git a/stack-core.el b/stack-core.el
index c43d34a..c2aff15 100644
--- a/stack-core.el
+++ b/stack-core.el
@@ -38,11 +38,16 @@
;;; Package Logging
(defun stack-message (format-string &rest args)
+ "Display a message"
(message "[stack] %s" (apply #'format format-string args)))
;;; Constants and Customizable Options
+(defcustom stack-cache-directory
+ (expand-file-name ".stackmode" user-emacs-directory)
+ "Directory containined cached files and precompiled filters.")
+
(defconst stack-core-api-version
"2.2"
"The current version of the API.")
@@ -54,7 +59,8 @@
(defcustom stack-core-default-keyword-arguments-alist
'(("filters/create")
("sites")
- (t (site . emacs)))
+ ("questions" (site . emacs))
+ (t nil))
"Keywords to use as the default for a given method.
The first element of each list is the method call the keywords
@@ -90,6 +96,10 @@ recent call. Set by `stack-core-make-request'.")
number, `stack-core-make-request' will begin printing out the
number of requests left every time it finishes a call.")
+(defcustom stack-core-silent-requests
+ t
+ "When `t', requests default to being silent.")
+
;;; Keyword Arguments
@@ -141,52 +151,127 @@ with the given KEYWORD-ARGUMENTS."
base
(concat base "?" args))))
-(defun stack-core-make-request (method &optional keyword-arguments filter)
+(defun stack-core-make-request
+ (method &optional keyword-arguments filter silent)
"Make a request to the StackExchange API using METHOD and
optional KEYWORD-ARGUMENTS. If no KEYWORD-ARGUMENTS are given,
`stack-core-default-keyword-arguments-alist' is used. Return the
entire response as a complex alist."
- (let* ((api-response
- (let ((call
- (stack-core-build-request
- method
- (cons `(filter . ,(cond
- (filter filter)
- ((boundp 'stack-filter)
- stack-filter)))
- (if keyword-arguments keyword-arguments
- (stack-core-get-default-keyword-arguments
- method)))))
- (url-automatic-caching stack-core-cache-requests))
- ;; TODO: url-retrieve-synchronously can return nil if the call is
- ;; unsuccessful should handle this case
- (stack-message "Request: %s" call)
- (with-current-buffer (url-retrieve-synchronously call)
- (goto-char (point-min))
- (if (not (search-forward "\n\n" nil t))
- (error "Response corrupted")
- (delete-region (point-min) (point))
- (buffer-string)))))
- (response
- (with-demoted-errors "JSON Error: %s"
- (json-read-from-string api-response))))
- (unless response
- (stack-message "Printing response as message")
- (message response)
- (error "Response could not be read by json-read-string"))
- (when (assoc 'error_id response)
- (error "Request failed: (%s) [%i %s] %s"
- method
- (cdr (assoc 'error_id response))
- (cdr (assoc 'error_name response))
- (cdr (assoc 'error_message response))))
- (setq stack-core-remaining-api-requests
- (cdr (assoc 'quota_remaining response)))
- (when (< stack-core-remaining-api-requests
- stack-core-remaining-api-requests-message-threshold)
- (stack-message "%d API requests remaining"
- stack-core-remaining-api-requests))
- (cdr (assoc 'items response))))
+ (let ((url-automatic-caching stack-core-cache-requests)
+ (url-inhibit-uncompression t)
+ (silent (or silent stack-core-silent-requests))
+ (call
+ (stack-core-build-request
+ method
+ (cons `(filter . ,(cond (filter filter)
+ ((boundp 'stack-filter) stack-filter)))
+ (if keyword-arguments keyword-arguments
+ (stack-core-get-default-keyword-arguments method))))))
+ ;; TODO: url-retrieve-synchronously can return nil if the call is
+ ;; unsuccessful should handle this case
+ (unless silent (stack-message "Request: %S" call))
+ (let ((response-buffer (cond
+ ((= emacs-minor-version 4)
+ (url-retrieve-synchronously call silent))
+ (t (url-retrieve-synchronously call)))))
+ (if (not response-buffer)
+ (error "Something went wrong in `url-retrieve-synchronously'")
+ (with-current-buffer response-buffer
+ (let* ((data (progn
+ (goto-char (point-min))
+ (if (not (search-forward "\n\n" nil t))
+ (error "Response headers missing")
+ (delete-region (point-min) (point))
+ (buffer-string))))
+ (response (ignore-errors
+ (json-read-from-string data))))
+ ;; if response isn't nil, the response was in plain text
+ (unless response
+ ;; try to decompress the response
+ (setq response
+ (with-demoted-errors "JSON Error: %s"
+ (shell-command-on-region
+ (point-min) (point-max)
+ stack-core-unzip-program
+ nil t)
+ (json-read-from-string
+ (buffer-substring
+ (point-min) (point-max)))))
+ ;; If it still fails, error out
+ (unless response
+ (stack-message "Unable to parse response")
+ (stack-message "Printing response as message")
+ (message "%S" response)
+ (error "Response could not be read by json-read-string")))
+ ;; At this point, either response is a valid data structure
+ ;; or we have already thrown an error
+ (when (assoc 'error_id response)
+ (error "Request failed: (%s) [%i %s] %s"
+ method
+ (cdr (assoc 'error_id response))
+ (cdr (assoc 'error_name response))
+ (cdr (assoc 'error_message response))))
+ (when (< (setq stack-core-remaining-api-requests
+ (cdr (assoc 'quota_remaining response)))
+ stack-core-remaining-api-requests-message-threshold)
+ (stack-message "%d API requests remaining"
+ stack-core-remaining-api-requests))
+ (cdr (assoc 'items response))))))))
+
+(defun stack-core-filter-data (data desired-tree)
+ "Filters DATA and returns the DESIRED-TREE"
+ (if (vectorp data)
+ (apply #'vector
+ (mapcar (lambda (entry)
+ (stack-core-filter-data
+ entry desired-tree))
+ data))
+ (delq
+ nil
+ (mapcar (lambda (cons-cell)
+ ;; TODO the resolution of `f' is O(2n) in the worst
+ ;; case. It may be faster to implement the same
+ ;; functionality as a `while' loop to stop looking the
+ ;; list once it has found a match. Do speed tests.
+ ;; See edfab4443ec3d376c31a38bef12d305838d3fa2e.
+ (let ((f (or (memq (car cons-cell) desired-tree)
+ (assoc (car cons-cell) desired-tree))))
+ (when f
+ (if (and (sequencep (cdr cons-cell))
+ (sequencep (elt (cdr cons-cell) 0)))
+ (cons (car cons-cell)
+ (stack-core-filter-data
+ (cdr cons-cell) (cdr f)))
+ cons-cell))))
+ data))))
+
+(defun stack-cache-get-file-name (filename)
+ "Expands FILENAME in the context of `stack-cache-directory'."
+ (expand-file-name filename stack-cache-directory))
+
+(defun stack-cache-get (cache)
+ "Return the data within CACHE.
+
+As with `stack-cache-set', CACHE is a file name within the
+context of `stack-cache-directory'."
+ (unless (file-exists-p stack-cache-directory)
+ (mkdir stack-cache-directory))
+ (let ((file (stack-cache-get-file-name cache)))
+ (when (file-exists-p file)
+ (with-temp-buffer
+ (insert-file-contents (stack-cache-get-file-name cache))
+ (read (buffer-string))))))
+
+(defun stack-cache-set (cache data)
+ "Set the content of CACHE to DATA.
+
+As with `stack-cache-get', CACHE is a file name within the
+context of `stack-cache-directory'."
+ (unless (file-exists-p stack-cache-directory)
+ (mkdir stack-cache-directory))
+ (write-region (prin1-to-string data) nil
+ (stack-cache-get-file-name cache))
+ data)
(provide 'stack-core)
;;; stack-core.el ends here
diff --git a/stack-filter.el b/stack-filter.el
index 1525a4b..4210549 100644
--- a/stack-filter.el
+++ b/stack-filter.el
@@ -32,9 +32,13 @@
;;; Customizations
+(defconst stack-filter-cache-file
+ "filters.el")
+
(defvar stack-filter
'default
- "The current filter. To customize the filter for the next call
+ "The current filter.
+To customize the filter for the next call
to `stack-core-make-request', let-bind this variable to the
output of a call to `stack-core-compile-filter'. Be careful! If
you're going to be using this new filter a lot, create a variable
@@ -42,28 +46,58 @@ for it. Creation requests count against
`stack-core-remaining-api-requests'!")
-;;; Filter compilation
+;;; Compilation
+;;; TODO allow BASE to be a precompiled filter name
(defun stack-filter-compile (&optional include exclude base)
- "Compile a StackExchange filter including fields from INCLUDE,
-excluding those from EXCLUDE, using BASE as a base filter.
+ "Compile INCLUDE and EXCLUDE into a filter derived from BASE.
INCLUDE and EXCLUDE must both be lists; BASE should be a symbol
or string."
(let ((keyword-arguments
- `((include . ,(if include (mapconcat
- #'stack-core-thing-as-string
- include ";")))
- (exclude . ,(if exclude (mapconcat
- #'stack-core-thing-as-string
- exclude ";")))
- (base . ,(if base base)))))
+ `((include . ,(if include (mapconcat
+ #'stack-core-thing-as-string
+ include ";")))
+ (exclude . ,(if exclude (mapconcat
+ #'stack-core-thing-as-string
+ exclude ";")))
+ (base . ,(if base base)))))
(let ((response (stack-core-make-request
- "filter/create"
- keyword-arguments)))
+ "filter/create"
+ keyword-arguments)))
(url-hexify-string
(cdr (assoc 'filter
- (elt response 0)))))))
+ (elt response 0)))))))
+
+
+;;; Storage and Retrieval
+
+(defun stack-filter-get (filter)
+ "Retrieve named FILTER from `stack-filter-cache-file'."
+ (cdr (assoc filter (stack-cache-get stack-filter-cache-file))))
+
+(defun stack-filter-store (name &optional filter)
+ "Store NAME as FILTER in `stack-filter-cache-file'.
+
+NAME should be a symbol and FILTER is a string as compiled by
+`stack-filter-compile'.
+
+If NAME is a cons cell, (car NAME) is taken to be the actual NAME
+and (cdr NAME) is taken to be the actual FILTER. In this case,
+the second argument is simply ignored."
+ (let ((name (if (consp name) (car name) name))
+ (filter (if (consp name) (cdr name) filter)))
+ (unless (symbolp name)
+ (error "Name must be a symbol: %S" name))
+ (let* ((dict (stack-cache-get stack-filter-cache-file))
+ (entry (assoc name dict)))
+ (if entry (setcdr entry filter)
+ (setq dict (cons (cons name filter) dict)))
+
+ (stack-cache-set stack-filter-cache-file dict))))
+
+(defun stack-filter-store-all (name-filter-alist)
+ (mapc #'stack-filter-store name-filter-alist))
(provide 'stack-filter)
;;; stack-filter.el ends here
diff --git a/stack-question.el b/stack-question.el
index 84f2367..10ff1fc 100644
--- a/stack-question.el
+++ b/stack-question.el
@@ -29,9 +29,12 @@
(require 'stack-filter)
(defvar stack-question-browse-filter
- (stack-filter-compile nil
+ (stack-filter-compile
+ nil
'(user.profile_image shallow_user.profile_image)))
+(stack-filter-store 'question-browse stack-question-browse-filter)
+
(defun stack-question-get-questions (site &optional page)
"Get the page PAGE of questions from SITE."
(stack-core-make-request
diff --git a/test/data-samples/questions.el b/test/data-samples/questions.el
new file mode 100644
index 0000000..4437e7a
--- /dev/null
+++ b/test/data-samples/questions.el
@@ -0,0 +1,517 @@
+[((title . "What are good tools for Emacs package development?")
+ (link . "http://emacs.stackexchange.com/questions/2949/what-are-good-tools-for-emacs-package-development")
+ (question_id . 2949)
+ (creation_date . 1414816866)
+ (last_activity_date . 1414816866)
+ (score . 0)
+ (answer_count . 1)
+ (view_count . 6)
+ (is_answered . :json-false)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2264/sean-allred")
+ (display_name . "Sean Allred")
+ (accept_rate . 75)
+ (user_type . "registered")
+ (user_id . 2264)
+ (reputation . 543))
+ (tags . ["elisp" "interactive-development" "package-development"]))
+((title . "Is there a &#39;local undo&#39; extension for Emacs?")
+ (link . "http://emacs.stackexchange.com/questions/2946/is-there-a-local-undo-extension-for-emacs")
+ (question_id . 2946)
+ (creation_date . 1414810154)
+ (last_activity_date . 1414813323)
+ (score . 3)
+ (answer_count . 1)
+ (accepted_answer_id . 2948)
+ (view_count . 10)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/600/mcb")
+ (display_name . "mcb")
+ (user_type . "registered")
+ (user_id . 600)
+ (reputation . 188))
+ (tags . ["editing"]))
+((title . "Helm color theme gets mixed results")
+ (link . "http://emacs.stackexchange.com/questions/2937/helm-color-theme-gets-mixed-results")
+ (question_id . 2937)
+ (creation_date . 1414795519)
+ (last_activity_date . 1414813299)
+ (score . 0)
+ (answer_count . 2)
+ (view_count . 16)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/35/ryan")
+ (display_name . "Ryan")
+ (user_type . "registered")
+ (user_id . 35)
+ (reputation . 255))
+ (tags . ["helm" "themes"]))
+((title . "`url-inhibit-uncompression` is ineffective; emulating curl with url.el")
+ (link . "http://emacs.stackexchange.com/questions/2947/url-inhibit-uncompression-is-ineffective-emulating-curl-with-url-el")
+ (question_id . 2947)
+ (creation_date . 1414812397)
+ (last_activity_date . 1414812397)
+ (score . 0)
+ (answer_count . 0)
+ (view_count . 3)
+ (is_answered . :json-false)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2264/sean-allred")
+ (display_name . "Sean Allred")
+ (accept_rate . 75)
+ (user_type . "registered")
+ (user_id . 2264)
+ (reputation . 543))
+ (tags . ["compression" "url"]))
+((title . "How can I bring back `nil`?")
+ (link . "http://emacs.stackexchange.com/questions/2935/how-can-i-bring-back-nil")
+ (question_id . 2935)
+ (last_edit_date . 1414799073)
+ (creation_date . 1414792387)
+ (last_activity_date . 1414805588)
+ (score . 5)
+ (answer_count . 1)
+ (accepted_answer_id . 2938)
+ (view_count . 133)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2264/sean-allred")
+ (display_name . "Sean Allred")
+ (accept_rate . 75)
+ (user_type . "registered")
+ (user_id . 2264)
+ (reputation . 543))
+ (tags . ["elisp" "interactive-development"]))
+((title . "org babel eval with no confirmation is explicit: :eval yes")
+ (link . "http://emacs.stackexchange.com/questions/2945/org-babel-eval-with-no-confirmation-is-explicit-eval-yes")
+ (question_id . 2945)
+ (creation_date . 1414805111)
+ (last_activity_date . 1414805111)
+ (score . 0)
+ (answer_count . 0)
+ (view_count . 5)
+ (is_answered . :json-false)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/55/wdkrnls")
+ (display_name . "wdkrnls")
+ (accept_rate . 100)
+ (user_type . "registered")
+ (user_id . 55)
+ (reputation . 362))
+ (tags . ["org-mode" "org-babel"]))
+((title . "Interpratation of Tabs in text copied from Emacs and pasted in other programs/editors")
+ (link . "http://emacs.stackexchange.com/questions/2944/interpratation-of-tabs-in-text-copied-from-emacs-and-pasted-in-other-programs-ed")
+ (question_id . 2944)
+ (creation_date . 1414804977)
+ (last_activity_date . 1414804977)
+ (score . 0)
+ (answer_count . 0)
+ (view_count . 5)
+ (is_answered . :json-false)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2248/adam")
+ (display_name . "Adam")
+ (accept_rate . 80)
+ (user_type . "registered")
+ (user_id . 2248)
+ (reputation . 227))
+ (tags . ["gnu-emacs"]))
+((title . "Calling the calc stack from babel: displaying percentages")
+ (link . "http://emacs.stackexchange.com/questions/2943/calling-the-calc-stack-from-babel-displaying-percentages")
+ (question_id . 2943)
+ (creation_date . 1414804647)
+ (last_activity_date . 1414804647)
+ (score . 0)
+ (answer_count . 0)
+ (view_count . 2)
+ (is_answered . :json-false)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/55/wdkrnls")
+ (display_name . "wdkrnls")
+ (accept_rate . 100)
+ (user_type . "registered")
+ (user_id . 55)
+ (reputation . 362))
+ (tags . ["org-mode" "org-babel" "calc"]))
+((title . "eldoc in python-mode")
+ (link . "http://emacs.stackexchange.com/questions/2942/eldoc-in-python-mode")
+ (question_id . 2942)
+ (creation_date . 1414800979)
+ (last_activity_date . 1414800979)
+ (score . 1)
+ (answer_count . 0)
+ (view_count . 9)
+ (is_answered . :json-false)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2191/nathaniel-flath")
+ (display_name . "Nathaniel Flath")
+ (accept_rate . 40)
+ (user_type . "registered")
+ (user_id . 2191)
+ (reputation . 170))
+ (tags . ["python" "eldoc" "customization"]))
+((title . "god-mode: swap keys")
+ (link . "http://emacs.stackexchange.com/questions/2903/god-mode-swap-keys")
+ (question_id . 2903)
+ (creation_date . 1414755674)
+ (last_activity_date . 1414800498)
+ (score . 2)
+ (answer_count . 2)
+ (accepted_answer_id . 2941)
+ (view_count . 42)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2005/rekado")
+ (display_name . "rekado")
+ (user_type . "registered")
+ (user_id . 2005)
+ (reputation . 875))
+ (tags . ["key-bindings" "keymap" "god-mode"]))
+((title . "How to make `truncate-lines` nil and `auto-fill-mode` off in magit buffers")
+ (link . "http://emacs.stackexchange.com/questions/2890/how-to-make-truncate-lines-nil-and-auto-fill-mode-off-in-magit-buffers")
+ (question_id . 2890)
+ (last_edit_date . 1414798728)
+ (creation_date . 1414730361)
+ (last_activity_date . 1414798728)
+ (score . 0)
+ (answer_count . 1)
+ (accepted_answer_id . 2895)
+ (view_count . 23)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/794/codychan")
+ (display_name . "CodyChan")
+ (user_type . "registered")
+ (user_id . 794)
+ (reputation . 125))
+ (tags . ["magit"]))
+((title . "How can I determine if a file is compressed from Elisp?")
+ (link . "http://emacs.stackexchange.com/questions/2931/how-can-i-determine-if-a-file-is-compressed-from-elisp")
+ (question_id . 2931)
+ (last_edit_date . 1414798025)
+ (creation_date . 1414789578)
+ (last_activity_date . 1414798025)
+ (score . 1)
+ (answer_count . 0)
+ (view_count . 18)
+ (is_answered . :json-false)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2264/sean-allred")
+ (display_name . "Sean Allred")
+ (accept_rate . 75)
+ (user_type . "registered")
+ (user_id . 2264)
+ (reputation . 543))
+ (tags . ["compression" "url"]))
+((title . "Focus-hook: attenuate colours when losing focus")
+ (link . "http://emacs.stackexchange.com/questions/2922/focus-hook-attenuate-colours-when-losing-focus")
+ (question_id . 2922)
+ (last_edit_date . 1414793447)
+ (creation_date . 1414774490)
+ (last_activity_date . 1414793447)
+ (score . 3)
+ (answer_count . 0)
+ (view_count . 20)
+ (is_answered . :json-false)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2005/rekado")
+ (display_name . "rekado")
+ (user_type . "registered")
+ (user_id . 2005)
+ (reputation . 875))
+ (tags . ["frames" "hooks" "focus"]))
+((title . "&quot;Making tag completion table&quot; Freezes/Blocks -- how to disable")
+ (link . "http://emacs.stackexchange.com/questions/2919/making-tag-completion-table-freezes-blocks-how-to-disable")
+ (question_id . 2919)
+ (creation_date . 1414770468)
+ (last_activity_date . 1414793088)
+ (score . 2)
+ (answer_count . 1)
+ (view_count . 21)
+ (is_answered . :json-false)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2265/cheezy")
+ (display_name . "cheezy")
+ (user_type . "registered")
+ (user_id . 2265)
+ (reputation . 11))
+ (tags . ["autocomplete" "performance" "ctags"]))
+((title . "Open edit-server files from emacsclient in a specific frame")
+ (link . "http://emacs.stackexchange.com/questions/2417/open-edit-server-files-from-emacsclient-in-a-specific-frame")
+ (question_id . 2417)
+ (last_edit_date . 1413990607)
+ (creation_date . 1413927107)
+ (last_activity_date . 1414790834)
+ (score . 5)
+ (answer_count . 2)
+ (view_count . 47)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/93/nispio")
+ (display_name . "nispio")
+ (accept_rate . 55)
+ (user_type . "registered")
+ (user_id . 93)
+ (reputation . 1714))
+ (tags . ["frames" "emacsclient"]))
+((title . "Babel doesn&#39;t wrap results in verbatim")
+ (link . "http://emacs.stackexchange.com/questions/2920/babel-doesnt-wrap-results-in-verbatim")
+ (question_id . 2920)
+ (last_edit_date . 1414770962)
+ (creation_date . 1414770503)
+ (last_activity_date . 1414784968)
+ (score . 0)
+ (answer_count . 1)
+ (view_count . 16)
+ (is_answered . :json-false)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/563/wvxvw")
+ (display_name . "wvxvw")
+ (user_type . "registered")
+ (user_id . 563)
+ (reputation . 255))
+ (tags . ["org-mode" "org-export" "org-babel"]))
+((title . "Can I change the background color of the inactive minibuffer?")
+ (link . "http://emacs.stackexchange.com/questions/2323/can-i-change-the-background-color-of-the-inactive-minibuffer")
+ (question_id . 2323)
+ (last_edit_date . 1413635904)
+ (creation_date . 1413626421)
+ (last_activity_date . 1414784512)
+ (score . 8)
+ (answer_count . 2)
+ (view_count . 93)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/600/mcb")
+ (display_name . "mcb")
+ (user_type . "registered")
+ (user_id . 600)
+ (reputation . 188))
+ (tags . ["customize" "faces" "minibuffer"]))
+((title . "Projectile project in folder without write access?")
+ (link . "http://emacs.stackexchange.com/questions/2891/projectile-project-in-folder-without-write-access")
+ (question_id . 2891)
+ (creation_date . 1414735834)
+ (last_activity_date . 1414784284)
+ (score . 2)
+ (answer_count . 2)
+ (view_count . 33)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/93/nispio")
+ (display_name . "nispio")
+ (accept_rate . 55)
+ (user_type . "registered")
+ (user_id . 93)
+ (reputation . 1714))
+ (tags . ["projectile"]))
+((title . "How to disable eldoc for `eval-expression`?")
+ (link . "http://emacs.stackexchange.com/questions/2917/how-to-disable-eldoc-for-eval-expression")
+ (question_id . 2917)
+ (last_edit_date . 1414770569)
+ (creation_date . 1414767244)
+ (last_activity_date . 1414776394)
+ (score . 1)
+ (answer_count . 1)
+ (accepted_answer_id . 2918)
+ (view_count . 35)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2094/abo-abo")
+ (display_name . "abo-abo")
+ (user_type . "registered")
+ (user_id . 2094)
+ (reputation . 430))
+ (tags . ["elisp" "emacs-25"]))
+((title . "How to view and edit large delimiter separated value files?")
+ (link . "http://emacs.stackexchange.com/questions/972/how-to-view-and-edit-large-delimiter-separated-value-files")
+ (question_id . 972)
+ (last_edit_date . 1414713136)
+ (creation_date . 1412881152)
+ (last_activity_date . 1414775451)
+ (score . 6)
+ (answer_count . 1)
+ (accepted_answer_id . 2923)
+ (view_count . 93)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/315/holocronweaver")
+ (display_name . "holocronweaver")
+ (user_type . "registered")
+ (user_id . 315)
+ (reputation . 55))
+ (tags . ["editing" "table" "large-files" "csv"]))
+((title . "The old &quot;how to fold xml&quot; question")
+ (link . "http://emacs.stackexchange.com/questions/2884/the-old-how-to-fold-xml-question")
+ (question_id . 2884)
+ (creation_date . 1414720950)
+ (last_activity_date . 1414773563)
+ (score . 5)
+ (answer_count . 1)
+ (view_count . 26)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/215/mark-aufflick")
+ (display_name . "Mark Aufflick")
+ (user_type . "registered")
+ (user_id . 215)
+ (reputation . 203))
+ (tags . ["xml" "nxml" "outline"]))
+((title . "How can I turn [1..10] into [1,2,3,4,5,6,7,8,9,10] in calc?")
+ (link . "http://emacs.stackexchange.com/questions/2914/how-can-i-turn-1-10-into-1-2-3-4-5-6-7-8-9-10-in-calc")
+ (question_id . 2914)
+ (creation_date . 1414765664)
+ (last_activity_date . 1414766835)
+ (score . 3)
+ (answer_count . 1)
+ (accepted_answer_id . 2916)
+ (view_count . 105)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/503/mrbones")
+ (display_name . "MrBones")
+ (user_type . "registered")
+ (user_id . 503)
+ (reputation . 118))
+ (tags . ["calc"]))
+((title . "How to turn off &quot;error&quot; highlighting in emacs-lisp-mode for Emacs 25?")
+ (link . "http://emacs.stackexchange.com/questions/2907/how-to-turn-off-error-highlighting-in-emacs-lisp-mode-for-emacs-25")
+ (question_id . 2907)
+ (last_edit_date . 1414766064)
+ (creation_date . 1414759846)
+ (last_activity_date . 1414766064)
+ (score . 2)
+ (answer_count . 1)
+ (accepted_answer_id . 2913)
+ (view_count . 50)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2094/abo-abo")
+ (display_name . "abo-abo")
+ (user_type . "registered")
+ (user_id . 2094)
+ (reputation . 430))
+ (tags . ["elisp" "font-lock" "emacs-lisp-mode"]))
+((title . "Kill buffer when frame is deleted")
+ (link . "http://emacs.stackexchange.com/questions/2888/kill-buffer-when-frame-is-deleted")
+ (question_id . 2888)
+ (creation_date . 1414725672)
+ (last_activity_date . 1414765666)
+ (score . 5)
+ (answer_count . 3)
+ (accepted_answer_id . 2915)
+ (view_count . 61)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/163/dharmatech")
+ (display_name . "dharmatech")
+ (user_type . "registered")
+ (user_id . 163)
+ (reputation . 216))
+ (tags . ["buffers" "frames"]))
+((title . "Is there a better way to handle multiline docstrings in elisp?")
+ (link . "http://emacs.stackexchange.com/questions/2887/is-there-a-better-way-to-handle-multiline-docstrings-in-elisp")
+ (question_id . 2887)
+ (last_edit_date . 1414741213)
+ (creation_date . 1414725439)
+ (last_activity_date . 1414764354)
+ (score . 7)
+ (answer_count . 3)
+ (view_count . 104)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2345/krazy-glew")
+ (display_name . "Krazy Glew")
+ (user_type . "registered")
+ (user_id . 2345)
+ (reputation . 136))
+ (tags . ["elisp" "documentation"]))
+((title . "TAB does not auto-indent lines anymore")
+ (link . "http://emacs.stackexchange.com/questions/2904/tab-does-not-auto-indent-lines-anymore")
+ (question_id . 2904)
+ (last_edit_date . 1414760438)
+ (creation_date . 1414757159)
+ (last_activity_date . 1414760438)
+ (score . 1)
+ (answer_count . 0)
+ (view_count . 30)
+ (is_answered . :json-false)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2305/vivian-maya")
+ (display_name . "Vivian Maya")
+ (user_type . "registered")
+ (user_id . 2305)
+ (reputation . 81))
+ (tags . ["indentation"]))
+((title . "Password/Key Management for multiple machines in emacs")
+ (link . "http://emacs.stackexchange.com/questions/2902/password-key-management-for-multiple-machines-in-emacs")
+ (question_id . 2902)
+ (creation_date . 1414755561)
+ (last_activity_date . 1414760173)
+ (score . 7)
+ (answer_count . 1)
+ (view_count . 64)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/294/gambo")
+ (display_name . "Gambo")
+ (user_type . "registered")
+ (user_id . 294)
+ (reputation . 175))
+ (tags . ["tramp"]))
+((title . "&quot;Symbol&#39;s function definition is void: cl-macroexpand-all&quot; when trying to install php-mode")
+ (link . "http://emacs.stackexchange.com/questions/2864/symbols-function-definition-is-void-cl-macroexpand-all-when-trying-to-instal")
+ (question_id . 2864)
+ (last_edit_date . 1414701459)
+ (creation_date . 1414700357)
+ (last_activity_date . 1414759512)
+ (score . 2)
+ (answer_count . 2)
+ (accepted_answer_id . 2866)
+ (view_count . 29)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/2342/cg433n")
+ (display_name . "cg433n")
+ (user_type . "registered")
+ (user_id . 2342)
+ (reputation . 13))
+ (tags . ["package" "cl-lib" "php-mode"]))
+((title . "Better debugging of crashing Emacs?")
+ (link . "http://emacs.stackexchange.com/questions/363/better-debugging-of-crashing-emacs")
+ (question_id . 363)
+ (last_edit_date . 1411830937)
+ (creation_date . 1411809580)
+ (last_activity_date . 1414757838)
+ (score . 5)
+ (answer_count . 2)
+ (accepted_answer_id . 373)
+ (view_count . 65)
+ (is_answered . t)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/249/gsl")
+ (display_name . "gsl")
+ (accept_rate . 100)
+ (user_type . "registered")
+ (user_id . 249)
+ (reputation . 84))
+ (tags . ["elisp" "fonts" "debugging" "crash"]))
+((title . "org-mode and reftex giving this error: reftex-using-biblatex-p: Stack overflow in regexp matcher")
+ (link . "http://emacs.stackexchange.com/questions/2901/org-mode-and-reftex-giving-this-error-reftex-using-biblatex-p-stack-overflow-i")
+ (question_id . 2901)
+ (last_edit_date . 1414754843)
+ (creation_date . 1414754222)
+ (last_activity_date . 1414754843)
+ (score . 0)
+ (answer_count . 0)
+ (view_count . 11)
+ (is_answered . :json-false)
+ (owner
+ (link . "http://emacs.stackexchange.com/users/201/petrux")
+ (display_name . "petrux")
+ (user_type . "registered")
+ (user_id . 201)
+ (reputation . 41))
+ (tags . ["org-mode" "reftex-mode" "bibtex"]))]
diff --git a/test/data-samples/sites.el b/test/data-samples/sites.el
new file mode 100644
index 0000000..9b02a39
--- /dev/null
+++ b/test/data-samples/sites.el
@@ -0,0 +1,711 @@
+[((site_type . "main_site")
+ (name . "Stack Overflow")
+ (logo_url . "http://cdn.sstatic.net/stackoverflow/img/logo.png")
+ (api_site_parameter . "stackoverflow")
+ (site_url . "http://stackoverflow.com")
+ (audience . "professional and enthusiast programmers")
+ (icon_url . "http://cdn.sstatic.net/stackoverflow/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/stackoverflow/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/stackoverflow/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (launch_date . 1221436800)
+ (markdown_extensions . ["Prettify"])
+ (aliases . ["http://www.stackoverflow.com" "http://facebook.stackoverflow.com"])
+ (related_sites . [((name . "Meta Stack Overflow")
+ (site_url . "http://meta.stackoverflow.com")
+ (api_site_parameter . "meta.stackoverflow")
+ (relation . "meta"))
+ ((name . "Stack Overflow Chat")
+ (site_url . "http://chat.stackoverflow.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#0077CC")
+ (tag_foreground_color . "#3E6D8E")
+ (tag_background_color . "#E0EAF1")))
+ ((site_type . "main_site")
+ (name . "Server Fault")
+ (logo_url . "http://cdn.sstatic.net/serverfault/img/logo.png")
+ (api_site_parameter . "serverfault")
+ (site_url . "http://serverfault.com")
+ (audience . "professional system and network administrators")
+ (icon_url . "http://cdn.sstatic.net/serverfault/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/serverfault/img/favicon.ico")
+ (twitter_account . "ServerFault")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/serverfault/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (launch_date . 1243296000)
+ (markdown_extensions . ["Prettify"])
+ (related_sites . [((name . "Meta Server Fault")
+ (site_url . "http://meta.serverfault.com")
+ (api_site_parameter . "meta.serverfault")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#10456A")
+ (tag_foreground_color . "#444444")
+ (tag_background_color . "#F3F1D9")))
+ ((site_type . "main_site")
+ (name . "Super User")
+ (logo_url . "http://cdn.sstatic.net/superuser/img/logo.png")
+ (api_site_parameter . "superuser")
+ (site_url . "http://superuser.com")
+ (audience . "computer enthusiasts and power users")
+ (icon_url . "http://cdn.sstatic.net/superuser/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/superuser/img/favicon.ico")
+ (twitter_account . "super_user")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/superuser/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (launch_date . 1250553600)
+ (markdown_extensions . ["Prettify"])
+ (related_sites . [((name . "Meta Super User")
+ (site_url . "http://meta.superuser.com")
+ (api_site_parameter . "meta.superuser")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#1086A4")
+ (tag_foreground_color . "#1087A4")
+ (tag_background_color . "#FFFFFF")))
+ ((site_type . "main_site")
+ (name . "Meta Stack Exchange")
+ (logo_url . "http://cdn.sstatic.net/stackexchangemeta/img/logo.png")
+ (api_site_parameter . "meta")
+ (site_url . "http://meta.stackexchange.com")
+ (audience . "meta-discussion of the Stack Exchange family of Q&amp;A websites")
+ (icon_url . "http://cdn.sstatic.net/stackexchangemeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/stackexchangemeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/stackexchangemeta/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (launch_date . 1246147200)
+ (markdown_extensions . ["Prettify"])
+ (related_sites . [((name . "Meta Stack Exchange Chat")
+ (site_url . "http://chat.meta.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#4E82C2")
+ (tag_foreground_color . "#566E76")
+ (tag_background_color . "#F7FDFF")))
+ ((site_type . "main_site")
+ (name . "Web Applications")
+ (logo_url . "http://cdn.sstatic.net/webapps/img/logo.png")
+ (api_site_parameter . "webapps")
+ (site_url . "http://webapps.stackexchange.com")
+ (audience . "power users of web applications")
+ (icon_url . "http://cdn.sstatic.net/webapps/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/webapps/img/favicon.ico")
+ (twitter_account . "StackWebApps")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/webapps/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (closed_beta_date . 1277856000)
+ (open_beta_date . 1278460800)
+ (launch_date . 1285804800)
+ (aliases . ["http://nothingtoinstall.com"])
+ (related_sites . [((name . "Web Applications Meta Stack Exchange")
+ (site_url . "http://meta.webapps.stackexchange.com")
+ (api_site_parameter . "meta.webapps")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#426389")
+ (tag_foreground_color . "#5D7A9C")
+ (tag_background_color . "#E2EDFA")))
+ ((site_type . "meta_site")
+ (name . "Web Applications Meta")
+ (logo_url . "http://cdn.sstatic.net/webappsmeta/img/logo.png")
+ (api_site_parameter . "meta.webapps")
+ (site_url . "http://meta.webapps.stackexchange.com")
+ (audience . "power users of web applications")
+ (icon_url . "http://cdn.sstatic.net/webappsmeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/webappsmeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/webappsmeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (aliases . ["http://meta.nothingtoinstall.com"])
+ (related_sites . [((name . "Web Applications Stack Exchange")
+ (site_url . "http://webapps.stackexchange.com")
+ (api_site_parameter . "webapps")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#333C43")
+ (tag_foreground_color . "#666")
+ (tag_background_color . "#EBEBEB")))
+ ((site_type . "main_site")
+ (name . "Arqade")
+ (logo_url . "http://cdn.sstatic.net/gaming/img/logo.png")
+ (api_site_parameter . "gaming")
+ (site_url . "http://gaming.stackexchange.com")
+ (audience . "passionate videogamers on all platforms")
+ (icon_url . "http://cdn.sstatic.net/gaming/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/gaming/img/favicon.ico")
+ (twitter_account . "TheArqade")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/gaming/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (closed_beta_date . 1278460800)
+ (open_beta_date . 1279065600)
+ (launch_date . 1286323200)
+ (aliases . ["http://arqade.com" "http://thearqade.com"])
+ (related_sites . [((name . "Arqade Meta")
+ (site_url . "http://meta.gaming.stackexchange.com")
+ (api_site_parameter . "meta.gaming")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#5A8F53")
+ (tag_foreground_color . "#666")
+ (tag_background_color . "#FFF")))
+ ((site_type . "meta_site")
+ (name . "Arqade Meta")
+ (logo_url . "http://cdn.sstatic.net/gamingmeta/img/logo.png")
+ (api_site_parameter . "meta.gaming")
+ (site_url . "http://meta.gaming.stackexchange.com")
+ (audience . "passionate videogamers on all platforms")
+ (icon_url . "http://cdn.sstatic.net/gamingmeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/gamingmeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/gamingmeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (aliases . ["http://meta.arqade.com" "http://meta.thearqade.com"])
+ (related_sites . [((name . "Arqade")
+ (site_url . "http://gaming.stackexchange.com")
+ (api_site_parameter . "gaming")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#666666")
+ (tag_foreground_color . "#666")
+ (tag_background_color . "#FFF")))
+ ((site_type . "main_site")
+ (name . "Webmasters")
+ (logo_url . "http://cdn.sstatic.net/webmasters/img/logo.png")
+ (api_site_parameter . "webmasters")
+ (site_url . "http://webmasters.stackexchange.com")
+ (audience . "pro webmasters")
+ (icon_url . "http://cdn.sstatic.net/webmasters/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/webmasters/img/favicon.ico")
+ (twitter_account . "StackWebmasters")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/webmasters/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (closed_beta_date . 1278547200)
+ (open_beta_date . 1279152000)
+ (launch_date . 1286928000)
+ (markdown_extensions . ["Prettify"])
+ (aliases . ["http://webmaster.stackexchange.com"])
+ (related_sites . [((name . "Webmasters Meta Stack Exchange")
+ (site_url . "http://meta.webmasters.stackexchange.com")
+ (api_site_parameter . "meta.webmasters")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#1C69A4")
+ (tag_foreground_color . "#1B8FBB")
+ (tag_background_color . "#FFF")))
+ ((site_type . "meta_site")
+ (name . "Webmasters Meta")
+ (logo_url . "http://cdn.sstatic.net/webmastersmeta/img/logo.png")
+ (api_site_parameter . "meta.webmasters")
+ (site_url . "http://meta.webmasters.stackexchange.com")
+ (audience . "pro webmasters")
+ (icon_url . "http://cdn.sstatic.net/webmastersmeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/webmastersmeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/webmastersmeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (markdown_extensions . ["Prettify"])
+ (aliases . ["http://meta.webmaster.stackexchange.com"])
+ (related_sites . [((name . "Webmasters Stack Exchange")
+ (site_url . "http://webmasters.stackexchange.com")
+ (api_site_parameter . "webmasters")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#3D3D3D")
+ (tag_foreground_color . "#666666")
+ (tag_background_color . "#FFF")))
+ ((site_type . "main_site")
+ (name . "Seasoned Advice")
+ (logo_url . "http://cdn.sstatic.net/cooking/img/logo.png")
+ (api_site_parameter . "cooking")
+ (site_url . "http://cooking.stackexchange.com")
+ (audience . "professional and amateur chefs")
+ (icon_url . "http://cdn.sstatic.net/cooking/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/cooking/img/favicon.ico")
+ (twitter_account . "StackCooking")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/cooking/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (closed_beta_date . 1278633600)
+ (open_beta_date . 1279238400)
+ (launch_date . 1287014400)
+ (aliases . ["http://seasonedadvice.com"])
+ (related_sites . [((name . "Seasoned Advice Meta")
+ (site_url . "http://meta.cooking.stackexchange.com")
+ (api_site_parameter . "meta.cooking")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#AB2020")
+ (tag_foreground_color . "#847454")
+ (tag_background_color . "#FFF5E4")))
+ ((site_type . "meta_site")
+ (name . "Seasoned Advice Meta")
+ (logo_url . "http://cdn.sstatic.net/cookingmeta/img/logo.png")
+ (api_site_parameter . "meta.cooking")
+ (site_url . "http://meta.cooking.stackexchange.com")
+ (audience . "professional and amateur chefs")
+ (icon_url . "http://cdn.sstatic.net/cookingmeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/cookingmeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/cookingmeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (aliases . ["http://meta.seasonedadvice.com"])
+ (related_sites . [((name . "Seasoned Advice")
+ (site_url . "http://cooking.stackexchange.com")
+ (api_site_parameter . "cooking")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#3D3D3D")
+ (tag_foreground_color . "#666666")
+ (tag_background_color . "#FFF")))
+ ((site_type . "main_site")
+ (name . "Game Development")
+ (logo_url . "http://cdn.sstatic.net/gamedev/img/logo.png")
+ (api_site_parameter . "gamedev")
+ (site_url . "http://gamedev.stackexchange.com")
+ (audience . "professional and independent game developers")
+ (icon_url . "http://cdn.sstatic.net/gamedev/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/gamedev/img/favicon.ico")
+ (twitter_account . "StackGameDev")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/gamedev/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (closed_beta_date . 1279065600)
+ (open_beta_date . 1279670400)
+ (launch_date . 1287619200)
+ (markdown_extensions . ["Prettify"])
+ (related_sites . [((name . "Game Development Meta Stack Exchange")
+ (site_url . "http://meta.gamedev.stackexchange.com")
+ (api_site_parameter . "meta.gamedev")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#416D63")
+ (tag_foreground_color . "#444444")
+ (tag_background_color . "#eeeeee")))
+ ((site_type . "meta_site")
+ (name . "Game Development Meta")
+ (logo_url . "http://cdn.sstatic.net/gamedevmeta/img/logo.png")
+ (api_site_parameter . "meta.gamedev")
+ (site_url . "http://meta.gamedev.stackexchange.com")
+ (audience . "professional and independent game developers")
+ (icon_url . "http://cdn.sstatic.net/gamedevmeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/gamedevmeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/gamedevmeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (related_sites . [((name . "Game Development Stack Exchange")
+ (site_url . "http://gamedev.stackexchange.com")
+ (api_site_parameter . "gamedev")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#3D3D3D")
+ (tag_foreground_color . "#666666")
+ (tag_background_color . "#FFF")))
+ ((site_type . "main_site")
+ (name . "Photography")
+ (logo_url . "http://cdn.sstatic.net/photo/img/logo.png")
+ (api_site_parameter . "photo")
+ (site_url . "http://photo.stackexchange.com")
+ (audience . "professional, enthusiast and amateur photographers")
+ (icon_url . "http://cdn.sstatic.net/photo/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/photo/img/favicon.ico")
+ (twitter_account . "StackPhotos")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/photo/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (closed_beta_date . 1279152000)
+ (open_beta_date . 1279756800)
+ (launch_date . 1288224000)
+ (aliases . ["http://photography.stackexchange.com" "http://photos.stackexchange.com"])
+ (related_sites . [((name . "Photography Meta Stack Exchange")
+ (site_url . "http://meta.photo.stackexchange.com")
+ (api_site_parameter . "meta.photo")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#0077CC")
+ (tag_foreground_color . "#444")
+ (tag_background_color . "#F7F7F7")))
+ ((site_type . "meta_site")
+ (name . "Photography Meta")
+ (logo_url . "http://cdn.sstatic.net/photometa/img/logo.png")
+ (api_site_parameter . "meta.photo")
+ (site_url . "http://meta.photo.stackexchange.com")
+ (audience . "professional, enthusiast and amateur photographers")
+ (icon_url . "http://cdn.sstatic.net/photometa/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/photometa/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/photometa/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (aliases . ["http://meta.photography.stackexchange.com" "http://meta.photos.stackexchange.com"])
+ (related_sites . [((name . "Photography Stack Exchange")
+ (site_url . "http://photo.stackexchange.com")
+ (api_site_parameter . "photo")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#3D3D3D")
+ (tag_foreground_color . "#666666")
+ (tag_background_color . "#FFF")))
+ ((site_type . "main_site")
+ (name . "Cross Validated")
+ (logo_url . "http://cdn.sstatic.net/stats/img/logo.png")
+ (api_site_parameter . "stats")
+ (site_url . "http://stats.stackexchange.com")
+ (audience . "people interested in statistics, machine learning, data analysis, data mining, and data visualization")
+ (icon_url . "http://cdn.sstatic.net/stats/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/stats/img/favicon.ico")
+ (twitter_account . "StackStats")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/stats/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (closed_beta_date . 1279497600)
+ (open_beta_date . 1280102400)
+ (launch_date . 1288828800)
+ (markdown_extensions . ["MathJax" "Prettify"])
+ (aliases . ["http://statistics.stackexchange.com" "http://crossvalidated.com"])
+ (related_sites . [((name . "Cross Validated Meta")
+ (site_url . "http://meta.stats.stackexchange.com")
+ (api_site_parameter . "meta.stats")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#0077CC")
+ (tag_foreground_color . "#5D5D5D")
+ (tag_background_color . "#edefed")))
+ ((site_type . "meta_site")
+ (name . "Cross Validated Meta")
+ (logo_url . "http://cdn.sstatic.net/statsmeta/img/logo.png")
+ (api_site_parameter . "meta.stats")
+ (site_url . "http://meta.stats.stackexchange.com")
+ (audience . "people interested in statistics, machine learning, data analysis, data mining, and data visualization")
+ (icon_url . "http://cdn.sstatic.net/statsmeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/statsmeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/statsmeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (markdown_extensions . ["MathJax"])
+ (aliases . ["http://meta.statistics.stackexchange.com"])
+ (related_sites . [((name . "Cross Validated")
+ (site_url . "http://stats.stackexchange.com")
+ (api_site_parameter . "stats")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#3D3D3D")
+ (tag_foreground_color . "#666666")
+ (tag_background_color . "#FFF")))
+ ((site_type . "main_site")
+ (name . "Mathematics")
+ (logo_url . "http://cdn.sstatic.net/math/img/logo.png")
+ (api_site_parameter . "math")
+ (site_url . "http://math.stackexchange.com")
+ (audience . "people studying math at any level and professionals in related fields")
+ (icon_url . "http://cdn.sstatic.net/math/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/math/img/favicon.ico")
+ (twitter_account . "StackMath")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/math/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (closed_beta_date . 1279584000)
+ (open_beta_date . 1280188800)
+ (launch_date . 1287964800)
+ (markdown_extensions . ["MathJax"])
+ (aliases . ["http://maths.stackexchange.com" "http://mathematics.stackexchange.com"])
+ (related_sites . [((name . "Mathematics Meta Stack Exchange")
+ (site_url . "http://meta.math.stackexchange.com")
+ (api_site_parameter . "meta.math")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#0077CC")
+ (tag_foreground_color . "#000")
+ (tag_background_color . "#888888")))
+ ((site_type . "meta_site")
+ (name . "Mathematics Meta")
+ (logo_url . "http://cdn.sstatic.net/mathmeta/img/logo.png")
+ (api_site_parameter . "meta.math")
+ (site_url . "http://meta.math.stackexchange.com")
+ (audience . "people studying math at any level and professionals in related fields")
+ (icon_url . "http://cdn.sstatic.net/mathmeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/mathmeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/mathmeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (markdown_extensions . ["MathJax"])
+ (related_sites . [((name . "Mathematics Stack Exchange")
+ (site_url . "http://math.stackexchange.com")
+ (api_site_parameter . "math")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#3D3D3D")
+ (tag_foreground_color . "#666666")
+ (tag_background_color . "#FFF")))
+ ((site_type . "main_site")
+ (name . "Home Improvement")
+ (logo_url . "http://cdn.sstatic.net/diy/img/logo.png")
+ (api_site_parameter . "diy")
+ (site_url . "http://diy.stackexchange.com")
+ (audience . "contractors and serious DIYers")
+ (icon_url . "http://cdn.sstatic.net/diy/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/diy/img/favicon.ico")
+ (twitter_account . "StackDIY")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/diy/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (closed_beta_date . 1279670400)
+ (open_beta_date . 1280275200)
+ (launch_date . 1299110400)
+ (related_sites . [((name . "Home Improvement Meta Stack Exchange")
+ (site_url . "http://meta.diy.stackexchange.com")
+ (api_site_parameter . "meta.diy")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#0077CC")
+ (tag_foreground_color . "#696969")
+ (tag_background_color . "#f5f5f5")))
+ ((site_type . "meta_site")
+ (name . "Home Improvement Meta")
+ (logo_url . "http://cdn.sstatic.net/diymeta/img/logo.png")
+ (api_site_parameter . "meta.diy")
+ (site_url . "http://meta.diy.stackexchange.com")
+ (audience . "contractors and serious DIYers")
+ (icon_url . "http://cdn.sstatic.net/diymeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/diymeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/diymeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (related_sites . [((name . "Home Improvement Stack Exchange")
+ (site_url . "http://diy.stackexchange.com")
+ (api_site_parameter . "diy")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#3D3D3D")
+ (tag_foreground_color . "#666666")
+ (tag_background_color . "#FFF")))
+ ((site_type . "meta_site")
+ (name . "Meta Super User")
+ (logo_url . "http://cdn.sstatic.net/superusermeta/img/logo.png")
+ (api_site_parameter . "meta.superuser")
+ (site_url . "http://meta.superuser.com")
+ (audience . "computer enthusiasts and power users")
+ (icon_url . "http://cdn.sstatic.net/superusermeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/superusermeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/superusermeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (markdown_extensions . ["Prettify"])
+ (related_sites . [((name . "Super User")
+ (site_url . "http://superuser.com")
+ (api_site_parameter . "superuser")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#0077CC")
+ (tag_foreground_color . "#000")
+ (tag_background_color . "#FFF")))
+ ((site_type . "meta_site")
+ (name . "Meta Server Fault")
+ (logo_url . "http://cdn.sstatic.net/serverfaultmeta/img/logo.png")
+ (api_site_parameter . "meta.serverfault")
+ (site_url . "http://meta.serverfault.com")
+ (audience . "system administrators and IT professionals")
+ (icon_url . "http://cdn.sstatic.net/serverfaultmeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/serverfaultmeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/serverfaultmeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (related_sites . [((name . "Server Fault")
+ (site_url . "http://serverfault.com")
+ (api_site_parameter . "serverfault")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#0077CC")
+ (tag_foreground_color . "#000")
+ (tag_background_color . "#FFF")))
+ ((site_type . "main_site")
+ (name . "Geographic Information Systems")
+ (logo_url . "http://cdn.sstatic.net/gis/img/logo-small.png")
+ (api_site_parameter . "gis")
+ (site_url . "http://gis.stackexchange.com")
+ (audience . "cartographers, geographers and GIS professionals")
+ (icon_url . "http://cdn.sstatic.net/gis/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/gis/img/favicon.ico")
+ (twitter_account . "StackGIS")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/gis/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (closed_beta_date . 1279756800)
+ (open_beta_date . 1280361600)
+ (launch_date . 1299456000)
+ (markdown_extensions . ["Prettify"])
+ (related_sites . [((name . "Geographic Information Systems Meta Stack Exchange")
+ (site_url . "http://meta.gis.stackexchange.com")
+ (api_site_parameter . "meta.gis")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#176F8C")
+ (tag_foreground_color . "#696969")
+ (tag_background_color . "#f5f5f5")))
+ ((site_type . "meta_site")
+ (name . "Geographic Information Systems Meta")
+ (logo_url . "http://cdn.sstatic.net/gismeta/img/logo-small.png")
+ (api_site_parameter . "meta.gis")
+ (site_url . "http://meta.gis.stackexchange.com")
+ (audience . "cartographers, geographers and GIS professionals")
+ (icon_url . "http://cdn.sstatic.net/gismeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/gismeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/gismeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (related_sites . [((name . "Geographic Information Systems Stack Exchange")
+ (site_url . "http://gis.stackexchange.com")
+ (api_site_parameter . "gis")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#3D3D3D")
+ (tag_foreground_color . "#666666")
+ (tag_background_color . "#FFF")))
+ ((site_type . "main_site")
+ (name . "TeX - LaTeX")
+ (logo_url . "http://cdn.sstatic.net/tex/img/logo.png")
+ (api_site_parameter . "tex")
+ (site_url . "http://tex.stackexchange.com")
+ (audience . "users of TeX, LaTeX, ConTeXt, and related typesetting systems")
+ (icon_url . "http://cdn.sstatic.net/tex/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/tex/img/favicon.ico")
+ (twitter_account . "StackTeX")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/tex/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (closed_beta_date . 1280102400)
+ (open_beta_date . 1280707200)
+ (launch_date . 1289433600)
+ (markdown_extensions . ["Prettify"])
+ (related_sites . [((name . "TeX - LaTeX Meta Stack Exchange")
+ (site_url . "http://meta.tex.stackexchange.com")
+ (api_site_parameter . "meta.tex")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#0077CC")
+ (tag_foreground_color . "#444444")
+ (tag_background_color . "#FEFEFA")))
+ ((site_type . "meta_site")
+ (name . "TeX - LaTeX Meta")
+ (logo_url . "http://cdn.sstatic.net/texmeta/img/logo.png")
+ (api_site_parameter . "meta.tex")
+ (site_url . "http://meta.tex.stackexchange.com")
+ (audience . "users of TeX, LaTeX, ConTeXt, and related typesetting systems")
+ (icon_url . "http://cdn.sstatic.net/texmeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/texmeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/texmeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (related_sites . [((name . "TeX - LaTeX Stack Exchange")
+ (site_url . "http://tex.stackexchange.com")
+ (api_site_parameter . "tex")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#3D3D3D")
+ (tag_foreground_color . "#666666")
+ (tag_background_color . "#FFF")))
+ ((site_type . "main_site")
+ (name . "Ask Ubuntu")
+ (logo_url . "http://cdn.sstatic.net/askubuntu/img/logo.png")
+ (api_site_parameter . "askubuntu")
+ (site_url . "http://askubuntu.com")
+ (audience . "Ubuntu users and developers")
+ (icon_url . "http://cdn.sstatic.net/askubuntu/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/askubuntu/img/favicon.ico")
+ (twitter_account . "AskUbuntu")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/askubuntu/img/apple-touch-icon@2.png")
+ (site_state . "normal")
+ (closed_beta_date . 1280275200)
+ (open_beta_date . 1280880000)
+ (launch_date . 1286668800)
+ (markdown_extensions . ["Prettify"])
+ (aliases . ["http://ubuntu.stackexchange.com"])
+ (related_sites . [((name . "Ask Ubuntu Meta")
+ (site_url . "http://meta.askubuntu.com")
+ (api_site_parameter . "meta.askubuntu")
+ (relation . "meta"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#333333")
+ (tag_foreground_color . "#5E5E5E")
+ (tag_background_color . "#E8E7E5")))
+ ((site_type . "meta_site")
+ (name . "Ask Ubuntu Meta")
+ (logo_url . "http://cdn.sstatic.net/askubuntumeta/img/logo.png")
+ (api_site_parameter . "meta.askubuntu")
+ (site_url . "http://meta.askubuntu.com")
+ (audience . "Ubuntu users and developers")
+ (icon_url . "http://cdn.sstatic.net/askubuntumeta/img/apple-touch-icon.png")
+ (favicon_url . "http://cdn.sstatic.net/askubuntumeta/img/favicon.ico")
+ (high_resolution_icon_url . "http://cdn.sstatic.net/askubuntumeta/img/apple-touch-icon@2.png")
+ (site_state . "linked_meta")
+ (aliases . ["http://meta.ubuntu.stackexchange.com"])
+ (related_sites . [((name . "Ask Ubuntu")
+ (site_url . "http://askubuntu.com")
+ (api_site_parameter . "askubuntu")
+ (relation . "parent"))
+ ((name . "Chat Stack Exchange")
+ (site_url . "http://chat.stackexchange.com")
+ (relation . "chat"))])
+ (styling
+ (link_color . "#222222")
+ (tag_foreground_color . "#5E5E5E")
+ (tag_background_color . "#E8E7E5")))]
diff --git a/test/tests.el b/test/tests.el
new file mode 100644
index 0000000..e097244
--- /dev/null
+++ b/test/tests.el
@@ -0,0 +1,97 @@
+(defun -stack--nuke ()
+ (interactive)
+ (mapatoms
+ (lambda (symbol)
+ (if (string-prefix-p "stack-" (symbol-name symbol))
+ (unintern symbol)))))
+
+;;; Tests
+
+(defun stack-test-sample-data (method &optional directory)
+ (let ((file (concat "data-samples/"
+ (when directory (concat directory "/"))
+ method ".el")))
+ (when (file-exists-p file)
+ (with-temp-buffer
+ (insert-file-contents file)
+ (read (buffer-string))))))
+
+(setq
+ stack-core-remaining-api-requests-message-threshold 50000
+ debug-on-error t
+ stack-core-silent-requests nil
+ user-emacs-directory "."
+
+ stack-test-data-questions
+ (stack-test-sample-data "questions")
+ stack-test-data-sites
+ (stack-test-sample-data "sites"))
+
+(require 'stack-core)
+(require 'stack-question)
+
+(ert-deftest test-basic-request ()
+ "Test basic request functionality"
+ (should (stack-core-make-request "sites")))
+
+(ert-deftest test-question-retrieve ()
+ "Test the ability to receive a list of questions."
+ (should (stack-question-get-questions 'emacs)))
+
+(ert-deftest test-bad-request ()
+ "Test a method given a bad set of keywords"
+ (should-error
+ (stack-core-make-request "questions" '(()))))
+
+(ert-deftest test-tree-filter ()
+ "`stack-core-filter-data'"
+ ;; flat
+ (should
+ (equal
+ '((1 . t) (2 . [1 2]) (3))
+ (stack-core-filter-data '((0 . 3) (1 . t) (a . five) (2 . [1 2])
+ ("5" . bop) (3) (p . 4))
+ '(1 2 3))))
+ ;; complex
+ (should
+ (equal
+ '((1 . [a b c])
+ (2 . [((a . 1) (c . 3))
+ ((a . 4) (c . 6))])
+ (3 . peach))
+ (stack-core-filter-data '((1 . [a b c])
+ (2 . [((a . 1) (b . 2) (c . 3))
+ ((a . 4) (b . 5) (c . 6))])
+ (3 . peach)
+ (4 . banana))
+ '(1 (2 a c) 3))))
+
+ ;; vector
+ (should
+ (equal
+ [((1 . 2) (2 . 3) (3 . 4))
+ ((1 . a) (2 . b) (3 . c))
+ nil ((1 . alpha) (2 . beta))]
+ (stack-core-filter-data [((1 . 2) (2 . 3) (3 . 4))
+ ((1 . a) (2 . b) (3 . c) (5 . seven))
+ ((should-not-go))
+ ((1 . alpha) (2 . beta))]
+ '(1 2 3)))))
+
+(ert-deftest test-filters ()
+ (let ((stack-cache-directory (make-temp-file "stack-test" t)))
+ (should-error (stack-filter-store "names must be symbols"
+ "this is a filter"))
+ ;; basic use
+ (should (equal '((test . "filter"))
+ (stack-filter-store 'test "filter")))
+ ;; aggregation
+ (should (equal '((test2 . "filter2") (test . "filter"))
+ (stack-filter-store 'test2 "filter2")))
+ ;; mutation
+ (should (equal '((test2 . "filter2") (test . "filter-test"))
+ (stack-filter-store 'test "filter-test")))
+ ;; clean up (note: the file should exist)
+ (delete-file
+ (stack-cache-get-file-name
+ stack-filter-cache-file))))
diff --git a/tests.el b/tests.el
deleted file mode 100644
index 0c2af0f..0000000
--- a/tests.el
+++ /dev/null
@@ -1,21 +0,0 @@
-(defun -stack--nuke ()
- (interactive)
- (mapatoms
- (lambda (symbol)
- (if (string-prefix-p "stack-" (symbol-name symbol))
- (unintern symbol)))))
-
-;;; Tests
-(setq debug-on-error t)
-
-(require 'stack-core)
-(require 'stack-question)
-
-(setq stack-core-remaining-api-requests-message-threshold 50000)
-
-(ert-deftest test-question-retrieve ()
- (should (stack-question-get-questions 'emacs)))
-
-(ert-deftest test-bad-request ()
- (should-error
- (stack-core-make-request "questions" '(()))))