diff --git a/AppRun b/AppImage/AppRun similarity index 100% rename from AppRun rename to AppImage/AppRun diff --git a/AppImage/strongbox.desktop b/AppImage/strongbox.desktop new file mode 100644 index 00000000..59df46ff --- /dev/null +++ b/AppImage/strongbox.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +# https://specifications.freedesktop.org/desktop-entry-spec/1.0/ +Type=Application +Version=1.0 +Name=Strongbox +GenericName=addon manager +Comment=World of Warcraft addon manager +Exec=AppRun +Terminal=false +Categories=Game;PackageManager;Java; +Icon=strongbox +Keywords=warcraft;wow;world of warcraft;elvui;tukui;wowinterface;github; diff --git a/CHANGELOG.md b/CHANGELOG.md index 100ed392..5e5ba86b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,35 @@ All notable changes to this project will be documented in this file. This change The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 6.1.0 - 2023-03-19 + +### Added + +* filtering search results by tag can now be switched between inclusive ('any of', default) and exclusive ('all of'). +* embedded font for glyphs used in the uber and star buttons for systems running with minimal fonts. + - https://github.com/ogri-la/strongbox/issues/384 +* an app launcher to desktop environments that support them. + - for me, `strongbox` was found under the `Games` menu item. + - only for installations via the AUR + - the `.desktop` file can be found here: https://github.com/ogri-la/strongbox-pkgbuild/blob/master/strongbox.desktop + +### Changed + +* search results filtered by tag are no longer sampled when no search input is available. + - this means you can now browse addons by tags alone if there are more addons that can fit on a single page of results. +* glyphs used for the uber and star buttons switched to their close equivalents in the new embedded font + - they're a little chunkier now but also look a little better in my estimation. +* moved some files used for building the AppImage from the root into a directory called `AppImage`. + +### Fixed + +* page >1 of search results that were then filtered further may have displayed the 'mascot' screen (ᕙ[°▿°]ᕗ) + - this was because the pagination wasn't being reset and there was no 'page N' for the given set of filters. + - the 'mascot' screen is still (deliberately) displayed in rare cases. +* characters in multi-line messages in the notice logger no longer get their descenders ('y', 'g', 'p', etc) truncated. +* ignored addons in the addon detail pane now display mutual dependencies (if any). +* 'WoW' column text was black with a dark background in dark mode, making the value illegible. + ## 6.0.0 - 2022-11-10 ### Added diff --git a/README.md b/README.md index 7b3b24c8..4353f94d 100644 --- a/README.md +++ b/README.md @@ -32,14 +32,14 @@ Arch Linux users can install `strongbox` from the [AUR](https://aur.archlinux.or For other Linux users: -1. download: [./releases/strongbox](https://github.com/ogri-la/strongbox/releases/download/6.0.0/strongbox) +1. download: [./releases/strongbox](https://github.com/ogri-la/strongbox/releases/download/6.1.0/strongbox) 2. make executable: `chmod +x strongbox` 3. run: `./strongbox` If you're on macOS or having a problem with the binary or just prefer Java `.jar` files (requires Java 11+): -1. download: [./releases/strongbox-6.0.0-standalone.jar](https://github.com/ogri-la/strongbox/releases/download/6.0.0/strongbox-6.0.0-standalone.jar) -2. run: `java -jar strongbox-6.0.0-standalone.jar` +1. download: [./releases/strongbox-6.1.0-standalone.jar](https://github.com/ogri-la/strongbox/releases/download/6.1.0/strongbox-6.1.0-standalone.jar) +2. run: `java -jar strongbox-6.1.0-standalone.jar` ## Usage diff --git a/TODO.md b/TODO.md index 078496fc..932a26b5 100644 --- a/TODO.md +++ b/TODO.md @@ -6,32 +6,18 @@ see CHANGELOG.md for a more formal list of changes by release ## done -* remove catalogue building logic - - this now lives in strongbox-catalogue-builder - - update scripts in strongbox-catalogue as well - - strongbox-catalogue is now just a dumb repository of catalogues again - - this will make this a major version release +* fonts are screwy on some systems + - https://github.com/ogri-la/strongbox/issues/384 + - embedded an older, smaller, lighter fontawesome and switched the glyphs - done -* remove wowman/v1 catalogue support - - done - -* remove tags - - done - -* add github to emergency catalogue - - done - -* cleanup - - done - -* add 'wotlk support' to comrades.csv - - done +* log pane, bug, the text 'catalogue' is being truncated in multi-line messages + - see screenshot Screenshot at 2022-09-24 08-56-35.png -* added support for dragonflight and six digit interface versions +* dark theme, 'wow' column text is black on black for some reason - done -* update screenshots +* add a .desktop file for AUR installations - done ## todo @@ -39,14 +25,38 @@ see CHANGELOG.md for a more formal list of changes by release ## todo bucket (no particular order) +* add support for cloning git repositories + - this is to get around addon repositories not uploading 'releases' when tagging + - switch between branches + - switch between tags + - could branches/tags be considered 'releases'? + - and what if we switch to a different branch and the folder structure changes? + - perhaps what we need is a separate place to clone these, and then *copy* them into the addons directory + - only available if local git available + - how to deal with local changes? + - have a policy of wiping out changes. or stashing changes. + - how to deal with repository being a mutual dependency? + - like, some other addon tries to overwrite it with their own version? + - we have ignore rules and pin rules already. + - can pinned addons be replaced? I've forgotten. + - how about a shallow clone? + - just the files are cloned to a directory + +* size of addon on disk + - I'd like to see a column with 'size on disk' + - "1024KiB", "1MiB", "1.04MB" + - I'd like to see a total size of all addons in addon dir + - "1024MiB", "1GiB" + - I'd like to see size of disk and free space + - "2TiB of 14TiB free" + - and everything mooshed together + - "1GiB of addons on /dev/foo with 2TiB of 14TiB available" + * wowinterface, fetch addon data from secondary source - *augment* what is currently implemented with my own source - failure to fetch this other data shouldn't prevent wowi updates from working normally - this source is hosted on github as static content, updated daily. -* log pane, bug, the text 'catalogue' is being truncated in multi-line messages - - see screenshot Screenshot at 2022-09-24 08-56-35.png - * 'core/state :db-stats', seems like a nice idea to put more information here - known-hosts - num addons per-host diff --git a/build-linux-image.sh b/build-linux-image.sh index bd756442..c05779f0 100755 --- a/build-linux-image.sh +++ b/build-linux-image.sh @@ -43,9 +43,9 @@ fi rm -rf ./AppDir mkdir AppDir mv "$output_dir" AppDir/usr -cp strongbox.desktop AppDir/ +cp AppImage/strongbox.desktop AppDir/ cp resources/strongbox.svg resources/strongbox.png AppDir/ -cp AppRun AppDir/ +cp AppImage/AppRun AppDir/ du -sh AppDir/ rm -f strongbox.appimage # safer than 'rm -f strongbox' ARCH=x86_64 ./appimagetool AppDir/ strongbox.appimage diff --git a/pom.xml b/pom.xml index 8b3419fb..fccfc3ad 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ ogri-la strongbox jar - 6.0.0 + 6.1.0 strongbox World Of Warcraft Addon Manager https://github.com/ogri-la/strongbox @@ -18,7 +18,7 @@ https://github.com/ogri-la/strongbox scm:git:git://github.com/ogri-la/strongbox.git scm:git:ssh://git@github.com/ogri-la/strongbox.git - 8b30744eb82428c403abdd5af6d636a41af4c091 + ed0d06e07da058c8b97330a5d5b97a6e033ce9be src diff --git a/project.clj b/project.clj index 5d9f9d9a..b8479c2b 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject ogri-la/strongbox "6.0.0" +(defproject ogri-la/strongbox "6.1.0" :description "World Of Warcraft Addon Manager" :url "https://github.com/ogri-la/strongbox" :license {:name "GNU Affero General Public License (AGPL)" diff --git a/release.md b/release.md index 5d3f00b1..9a280ef3 100644 --- a/release.md +++ b/release.md @@ -17,6 +17,7 @@ git checkout master git pull git checkout develop git merge master +lein clean truncate TODO update CHANGELOG with new sections from bottom diff --git a/resources/fontawesome-4.7.0.ttf b/resources/fontawesome-4.7.0.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/resources/fontawesome-4.7.0.ttf differ diff --git a/src/strongbox/cli.clj b/src/strongbox/cli.clj index f86d5894..d761acb9 100644 --- a/src/strongbox/cli.clj +++ b/src/strongbox/cli.clj @@ -197,23 +197,33 @@ (doseq [path path-list] (core/state-bind path listener)))) +(defn-spec reset-search-navigation nil? + "returns the search results to page 1" + [] + (swap! core/state assoc-in [:search :page] 0) + nil) + (defn-spec search-add-filter nil? "adds a new filter to the search `filter-by` state." [filter-by :search/filter-by, val any?] + (reset-search-navigation) (case filter-by :source (swap! core/state assoc-in [:search :filter-by filter-by] (utils/nilable val)) - :tag (swap! core/state update-in [:search :filter-by filter-by] conj val)) + :tag (swap! core/state update-in [:search :filter-by filter-by] conj val) + :tag-membership (swap! core/state assoc-in [:search :filter-by filter-by] val)) nil) (defn-spec search-rm-filter nil? "removes a filter from the search `filter-by` state." [filter-by :search/filter-by, val any?] + (reset-search-navigation) (swap! core/state update-in [:search :filter-by filter-by] clojure.set/difference #{val}) nil) (defn-spec search-toggle-filter nil? "toggles boolean filters on and off" [filter-by :search/filter-by] + (reset-search-navigation) (swap! core/state update-in [:search :filter-by filter-by] not) nil) diff --git a/src/strongbox/constants.clj b/src/strongbox/constants.clj index 7fb1d39f..09c63e62 100644 --- a/src/strongbox/constants.clj +++ b/src/strongbox/constants.clj @@ -37,16 +37,32 @@ ;; like during testing the formatting of date durations. (def fake-date "2001-01-01") -(def glyph-map +(def glyph-map--regular {:tick "\u2714" ;; '✔' :unsteady "\u2941" ;; '⥁' CLOCKWISE CLOSED CIRCLE ARROW :warnings "\u2501" ;; '━' heavy horizontal - :errors "\u2A2F" ;; '⨯' - :update "\u21A6" ;; '↦' + :errors "\u2A2F" ;; '⨯' vector or cross product + :update "\u21A6" ;; '↦' rightwards arrow from bar :ignored "\u26AA" ;; '⚪' medium white circle :pinned "\u26ab" ;; '⚫' medium black circle + :star "\u2605" ;; '★' black star + :right-arrow "\u2794" ;; '➔' HEAVY WIDE-HEADED RIGHTWARDS ARROW }) +(def glyph-map--fontawesome + {:tick "\uf00c" ;; check + :unsteady "\uf021" ;; arrows rotate + :warnings "\uf068" ;; minus + :errors "\uf00d" ;; xmark + :update "\uf061" ;; arrow-right + :ignored "\uf056" ;; circle minus + :pinned "\uf192" ;; circle dot + :star "\uf005" ;; star + :right-arrow "\uf061" ;; arrow-right + }) + +(def glyph-map glyph-map--fontawesome) + (def curseforge-cutoff-label "Feb 1st, 2022") (def releases diff --git a/src/strongbox/core.clj b/src/strongbox/core.clj index 93201278..31681393 100644 --- a/src/strongbox/core.clj +++ b/src/strongbox/core.clj @@ -82,6 +82,7 @@ {:term nil :filter-by {:source nil :tag #{} + :tag-membership "any of" ;; "all of" :user-catalogue false} :page 0 :results [] @@ -872,13 +873,20 @@ (utils/in? (:source row) source-list)) constantly-true) - tag-set (:tag filter-by) - tag-filter (if-not (empty? tag-set) - (fn [row] - (if-let [row-tag-set (set (:tag-list row))] - ;; if the addon contains *some* of the selected tags, include it - (some tag-set row-tag-set))) - constantly-true) + selected-tag-set (:tag filter-by) + tag-filter (if (empty? selected-tag-set) + constantly-true + (fn [addon] + (let [addon-tag-set (-> addon :tag-list set) + tag-membership (:tag-membership filter-by)] + (cond + ;; exclude addon if tags have been selected but it has no tags + (empty? addon-tag-set) false + ;; include addon if it contains *some* of the selected tags + (= tag-membership "any of") (some selected-tag-set addon-tag-set) + ;; include addon if it contains *all* of the selected tags + (= tag-membership "all of") (clojure.set/subset? selected-tag-set addon-tag-set) + :else false)))) db (->> db (filter user-catalogue-filter) @@ -886,6 +894,7 @@ (filter tag-filter)) random-sample? (and (nil? uin) + (empty? selected-tag-set) (not (:user-catalogue filter-by)))] ;; no/empty input, do a random sample diff --git a/src/strongbox/jfx.clj b/src/strongbox/jfx.clj index a85ed6cd..9877c3a8 100644 --- a/src/strongbox/jfx.clj +++ b/src/strongbox/jfx.clj @@ -3,6 +3,7 @@ [me.raynes.fs :as fs] [clojure.pprint] [clojure.set] + [clojure.java.io :as io] ;;[clojure.core.cache :as cache] [clojure.string :refer [lower-case join capitalize replace] :rename {replace str-replace}] ;; logging in the gui should be avoided as it can lead to infinite loops @@ -28,6 +29,7 @@ [utils :as utils :refer [no-new-lines message-list]] [core :as core]]) (:import + [javafx.scene.text Font] [java.util List Calendar Locale] [javafx.util Callback] [javafx.scene.control TreeTableRow TableRow TextInputDialog Alert Alert$AlertType ButtonType] @@ -38,6 +40,12 @@ [javafx.event Event] [java.text NumberFormat])) +(defn load-font-from-resources + [resource] + (-> resource io/resource str (Font/loadFont 40.0))) + +(def embedded-font (load-font-from-resources "fontawesome-4.7.0.ttf")) + ;; javafx hack, fixes combobox that sometimes goes blank: ;; - https://github.com/cljfx/cljfx/issues/76#issuecomment-645563116 (def ext-recreate-on-key-changed @@ -369,7 +377,7 @@ :-fx-spacing "1em"} ".big-welcome-subtext" - {:-fx-font-size "1.8em" + {:-fx-font-size "1.6em" :-fx-font-family "monospace" :-fx-padding ".8em 0 1em 0"}} @@ -387,10 +395,17 @@ {".wow-column" {:-fx-alignment "center"} + ;; 2023-03-04: 'WoW' column text was black in dark mode, missing styling from 'table-cell'. + ;; added 'table-cell' to the :game-version `:desc`, but then it had a border-right-width of 1, + ;; which is only present in buttons. not sure what is going on but this fixes that. + ".wow-column .table-cell" + {:-fx-border-width "0"} + ".uber-button" - {:-fx-font-size "1.5em" + {:-fx-font-size "1.3em" + :-fx-padding "1 0" :-fx-text-fill (colour :uber-button-tick) ;; green tick - :-fx-font-weight "bold"} + :-fx-font-family "'FontAwesome'"} ".table-row-cell.warnings .invisible-button-column > .uber-button" {;; orange bar @@ -463,7 +478,10 @@ {:-fx-alignment "center"} "#message.column-header .label" - {:-fx-alignment "center-left"}} + {:-fx-alignment "center-left"} + + ".table-row-cell .message-text" + {:-fx-fill "-fx-text-background-color"}} ;; ;; notice-logger-nav @@ -485,8 +503,8 @@ {:-fx-text-fill (colour :star-hover)} ".star-column > .button" - {:-fx-padding "-0.25em !important" - :-fx-font-size "1.9em" + {:-fx-padding "1 0" + :-fx-font-size "1.3em" :-fx-text-fill (colour :star-unstarred) ".starred" @@ -500,8 +518,8 @@ "#search-user-catalogue-button" {:-fx-font-weight "bold" - :-fx-font-size "1.4em" - :-fx-padding "1 7" + :-fx-font-size "1.2em" + :-fx-padding "2 7 " ".starred" {:-fx-text-fill (colour :star-starred) ;; the yellow of the star doesn't stand out from the gray gradient behind it. @@ -1251,6 +1269,7 @@ ;; the tooltip will be long and intrusive, make delay longer than typical. :show-delay 400}} :desc {:fx/type :label + :style-class ["table-cell"] :text text}}}))}} :uber-button {:min-width 80 :pref-width 80 :max-width 120 :style-class ["invisible-button-column"] @@ -1694,7 +1713,9 @@ :text "STRONGBOX"} {:fx/type :label :style-class ["big-welcome-subtext"] - :text "\"File\" \u2794 \"New addon directory\""}]} + ;; note! glyph is using FontAwesome map but the font-family is 'monospace'. + ;; it could be java is looking for missing glyphs in other loaded fonts? + :text (str "\"File\" " (:right-arrow constants/glyph-map) " \"New addon directory\"")}]} (empty? column-list) {:fx/type :v-box @@ -1780,7 +1801,13 @@ column-list [{:id "source" :text "source" :pref-width source-width :max-width source-width :min-width source-width :cell-value-factory source-label} {:id "level" :text "level" :max-width 80 :cell-value-factory (comp name :level)} {:id "time" :text "time" :max-width 100 :cell-value-factory :time} - {:id "message" :text "message" :pref-width 500 :cell-value-factory :message}] + {:id "message" :text "message" :pref-width 500 + :cell-factory {:fx/cell-type :table-cell + :describe (fn [row] + {:graphic {:fx/type :text + :style-class ["message-text"] + :text (get row :message "")}})} + :cell-value-factory identity}] log-level-list [:debug :info :warn :error] ;; :report] ;; 'reports' won't be interesting, no need to filter by them right now. log-level-list (if-not (contains? level-occurances :debug) @@ -1863,12 +1890,18 @@ ;; rare case when there are precisely $cap results, the next page is empty empty-next-page (and (= 0 (count addon-list)) - (> (-> search-state :page) 0)) + (-> search-state :page (> 0))) tag-set (-> search-state :filter-by :tag) tag-selected (fn [tag] (some #{tag} tag-set)) + tag-button (fn [tag] + (when-not (tag-selected tag) + (button (name tag) + (async-handler #(cli/search-add-filter :tag tag)) + {:tooltip (name tag)}))) + column-list [{:text "" :style-class ["invisible-button-column" "star-column"] :min-width 50 :pref-width 50 :max-width 50 :cell-value-factory identity @@ -1876,7 +1909,7 @@ :describe (fn [addon-summary] (let [starred (starred? addon-summary) f (if starred cli/remove-summary-from-user-catalogue cli/add-summary-to-user-catalogue)] - {:graphic (button "\u2605" + {:graphic (button (:star constants/glyph-map) (async-handler (partial f addon-summary)) {:style-class (if starred "starred" "unstarred")})}))}} @@ -1892,13 +1925,7 @@ :cell-factory {:fx/cell-type :table-cell :describe (fn [row] {:graphic {:fx/type :h-box - :children (remove nil? - (map (fn [tag] - (when-not (tag-selected tag) - (button (name tag) - (async-handler #(cli/search-add-filter :tag tag)) - {:tooltip (name tag)}))) - (:tag-list row)))}})}} + :children (remove nil? (map tag-button (:tag-list row)))}})}} {:text "updated" :min-width 90 :pref-width 110 :max-width 120 :resizable false :cell-value-factory :updated-date :cell-factory {:fx/cell-type :table-cell @@ -1956,6 +1983,18 @@ tag-button (fn [tag] (button (name tag) (async-handler #(cli/search-rm-filter :tag tag)))) + tag-membership ["any of" "all of"] + tag-any-all {:fx/type :combo-box + :id "tag-any-all-of" + :value (first tag-membership) + :on-value-changed (async-event-handler #(cli/search-add-filter :tag-membership %)) + :items tag-membership} + + tag-buttons (mapv tag-button tag-set) + tag-buttons (if-not (empty? tag-buttons) + (into [tag-any-all] tag-buttons) + []) + num-selected (count (:selected-result-list search-state)) row-1 {:fx/type :h-box @@ -1977,7 +2016,7 @@ :text (core/get-state :search :term) ;; this seems ok, probably has it's own drawbacks :on-text-changed cli/search} - (button "\u2605" (async-handler #(cli/search-toggle-filter :user-catalogue)) + (button (:star constants/glyph-map) (async-handler #(cli/search-toggle-filter :user-catalogue)) {:id "search-user-catalogue-button" :style-class (if (-> search-state :filter-by :user-catalogue) "starred" "unstarred")}) @@ -2012,7 +2051,7 @@ row-2 {:fx/type :h-box :id "search-selected-tag-bar" - :children (mapv tag-button tag-set)}] + :children tag-buttons}] (if (empty? tag-set) row-1 @@ -2164,24 +2203,25 @@ :value row}) to-children (fn [a b] - (assoc b :children [a])) + (if (empty? a) + b + (assoc b :children [a]))) install-dir (core/get-state :cfg :selected-addon-dir) children (if-not (:dirname addon) ;; search result [] - ;; todo: move this logic to addon or cli and remove 'nfo' from includes ;; installed addon. read the raw nfo data and create a hierarchy of lowest->highest (see to-children) (for [grouped-addon (addon/flatten-addon addon) :let [mut-deps (nfo/mutual-dependencies install-dir (:dirname grouped-addon)) mut-deps-tree-items (map (fn [nfo] (to-tree-rows (merge grouped-addon nfo))) mut-deps)]] - (reduce to-children mut-deps-tree-items))) + (reduce to-children {} mut-deps-tree-items))) root {:fx/type :tree-item :expanded true - :children children} + :children (remove empty? children)} ;; we need a depth > 1 to show anything meaningful depth (utils/find-depth root 0) diff --git a/src/strongbox/nfo.clj b/src/strongbox/nfo.clj index 5376c8f6..107954e3 100644 --- a/src/strongbox/nfo.clj +++ b/src/strongbox/nfo.clj @@ -135,9 +135,10 @@ "returns a list of `addon/nfo` data for addons using the given `addon-dirname` (including itself)." [install-dir ::sp/extant-dir, addon-dirname ::sp/dirname] (let [contents (read-nfo-file install-dir addon-dirname)] - (if (vector? contents) - contents - [contents]))) + (cond + (nil? contents) [] ;; an ignored addon may not have nfo data + (not (vector? contents)) [contents] + :else contents))) (defn-spec mutual-dependency? boolean? "returns `true` if multiple sets of nfo data exist in file" diff --git a/src/strongbox/specs.clj b/src/strongbox/specs.clj index ab8bdd07..afdd2a29 100644 --- a/src/strongbox/specs.clj +++ b/src/strongbox/specs.clj @@ -452,4 +452,4 @@ ;; search -(s/def :search/filter-by #{:source :tag :user-catalogue}) +(s/def :search/filter-by #{:source :tag :tag-membership :user-catalogue}) diff --git a/strongbox.desktop b/strongbox.desktop deleted file mode 100644 index 3b97794c..00000000 --- a/strongbox.desktop +++ /dev/null @@ -1,8 +0,0 @@ -[Desktop Entry] -# https://specifications.freedesktop.org/desktop-entry-spec/latest/ -Type=Application -Name=strongbox -#Version=1.0 -Exec=AppRun -Categories=Game;PackageManager;Java; -Icon=strongbox diff --git a/test/strongbox/cli_test.clj b/test/strongbox/cli_test.clj index 027e71d5..a08c1338 100644 --- a/test/strongbox/cli_test.clj +++ b/test/strongbox/cli_test.clj @@ -134,7 +134,7 @@ (let [catalogue (slurp (fixture-path "catalogue--v2.json")) fake-routes {"https://raw.githubusercontent.com/ogri-la/strongbox-catalogue/master/short-catalogue.json" {:get (fn [req] {:status 200 :body catalogue})}} - page-1 0] + page-1 first] (with-global-fake-routes-in-isolation fake-routes (with-running-app ;; populate the search @@ -142,26 +142,42 @@ (Thread/sleep 10) ;; sanity check - (is (= 4 (count (core/get-state :search :results page-1)))) + (is (= 4 (-> (core/get-state :search :results) page-1 count))) (cli/search-add-filter :tag :ui) (is (= #{:ui} (core/get-state :search :filter-by :tag))) (Thread/sleep 10) - (is (= 1 (count (core/get-state :search :results page-1)))) - (is (= "tukui" (-> (core/get-state :search :results page-1) first :source))) - ;; results are OR'ed + (is (= 1 (-> (core/get-state :search :results) page-1 count))) + (is (= "tukui" (-> (core/get-state :search :results) page-1 first :source))) + + ;; results are OR'ed by default ... (cli/search-add-filter :tag :vendors) (is (= #{:vendors :ui} (core/get-state :search :filter-by :tag))) (Thread/sleep 10) - (is (= 2 (count (core/get-state :search :results page-1)))) - (is (= "wowinterface" (->> (core/get-state :search :results page-1) first :source))) - (is (= "tukui" (-> (core/get-state :search :results page-1) second :source))) + (is (= 2 (-> (core/get-state :search :results) page-1 count))) + (is (= "wowinterface" (->> (core/get-state :search :results) page-1 first :source))) + (is (= "tukui" (-> (core/get-state :search :results) page-1 second :source))) + + ;; ... but can also be AND'ed + (cli/search-add-filter :tag-membership "all of") + (is (= "all of" (core/get-state :search :filter-by :tag-membership))) + (Thread/sleep 10) + + ;; (no addons tagged with both 'ui' and 'vendors') + (is (= 0 (-> (core/get-state :search :results) page-1 count))) ;; filters can be removed (cli/search-rm-filter :tag :ui) (is (= #{:vendors} (core/get-state :search :filter-by :tag))) - (is (= "wowinterface" (->> (core/get-state :search :results page-1) first :source)))))))) + (Thread/sleep 10) + (is (= "wowinterface" (->> (core/get-state :search :results) page-1 first :source))) + + (cli/search-add-filter :tag :auction-house) + (is (= #{:vendors :auction-house} (core/get-state :search :filter-by :tag))) + (Thread/sleep 10) + (is (= 1 (-> (core/get-state :search :results) page-1 count))) + (is (= "wowinterface" (->> (core/get-state :search :results) page-1 first :source)))))))) (deftest search-db--navigate (testing "a populated database can be searched forwards and backwards from the CLI"