Commit 8fb2a3f3 authored by Ricardo J. Mendez's avatar Ricardo J. Mendez

New tests for time scoring functions

- Refactored scoring functions to their own namespace so I can test
  them (otherwise we run into a Chrome dependency)
- BUGFIX: A page wasn't inheriting its site's score if the page was
  unknown

https://app.asana.com/0/50978096561390/75288306212813
parent 201f9679
......@@ -4,6 +4,7 @@
[relevance.data :as data]
[relevance.io :as io]
[relevance.migrations :as migrations]
[relevance.order :refer [time-score score-tabs]]
[relevance.utils :refer [on-channel url-key host-key hostname is-http? ms-day]]
[relevance.settings :refer [default-settings]]
[khroma.alarms :as alarms]
......@@ -27,8 +28,6 @@
(def window-alarm "window-alarm")
(def non-http-penalty 0.01)
(def sound-extra-score 9888777666)
(def relevant-tab-keys [:windowId :id :active :url :start-time :title :favIconUrl :audible])
(def select-tab-keys #(select-keys % relevant-tab-keys))
......@@ -96,33 +95,14 @@
(tabs/create {:url ext-url})))))
(defn time-score [tab url-times site-times settings]
(let [url (:url tab)
idx (:index tab)
url-time (:time (get url-times (url-key url)))
is-priority? (and (:sound-to-left? settings)
(:audible tab))
tab-time (if is-priority?
(+ sound-extra-score idx)
url-time)
site-time (:time (get site-times (host-key (hostname url))))
total (+ tab-time site-time)
is-penalized? (and (not (is-http? url))
(not is-priority?))
score (if is-penalized? (* total non-http-penalty) total)]
(or (when tab-time score)
(- idx))))
(defn sort-tabs! [window-id app-state]
(go
(let [{:keys [settings data]} app-state
{:keys [url-times site-times]} data
tabs (->> (:tabs (<! (windows/get window-id)))
(map #(assoc % :time (time-score % url-times site-times settings)))
(sort-by #(* -1 (:time %)))
(map-indexed #(hash-map :index %1
:id (:id %2))))]
tabs (score-tabs (:tabs (<! (windows/get window-id)))
url-times
site-times
settings)]
(doseq [tab tabs]
(tabs/move (:id tab) {:index (:index tab)})))))
......
(ns relevance.order
(:require [relevance.utils :refer [on-channel url-key host-key hostname is-http? ms-day]]))
;;;;------------------------------------
;;;; Settings
;;;;------------------------------------
(def non-http-penalty 0.01)
(def sound-extra-score 9888777666)
;;;;------------------------------------
;;;; Functions
;;;;------------------------------------
(defn time-score
"Returns a score for a tab based on the total time spent at both URLs and sites"
[tab url-times site-times settings]
(let [url (:url tab)
idx (:index tab)
url-time (or (:time (get url-times (url-key url)))
0)
is-priority? (and (:sound-to-left? settings)
(:audible tab))
is-penalized? (and (not (is-http? url))
(not is-priority?))
tab-time (cond
; Add an extra score if it's a priority URL
is-priority? (+ sound-extra-score idx)
; If a URL is penalized, we want it to at least have a
; value of 1, otherwise the tab time gets ignored and
; we'd default to using the raw site time
is-penalized? (max url-time 1)
; ... otherwise we just go with the raw URL time
:else url-time)
site-time (or (:time (get site-times (host-key (hostname url)))) 0)
total (+ tab-time site-time)
score (if is-penalized? (* total non-http-penalty) total)]
(or (when (pos? tab-time) score)
(- site-time idx))))
(defn score-tabs
"Returns a hashmap of the new tab ids and their indexes, based on a tab list and
the score function for time spent on urls and sites."
[tabs url-times site-times settings]
(->> tabs
(map #(assoc % :time (time-score % url-times site-times settings)))
(sort-by #(* -1 (:time %)))
(map-indexed #(hash-map :index %1
:id (:id %2)))))
(ns relevance.test.order
(:require [cljs.test :refer-macros [deftest testing is are]]
[relevance.data :as data]
[relevance.order :as order]
[relevance.utils :as utils]))
(deftest empty-test
(is (= 1 1)))
(deftest test-time-score
; A score for an unknown URL with no tab index is zero
(is (= 0 (order/time-score {:url "http://google.com"}
{}
{}
{})))
; A score for an unknown URL with no tab index is the complement of its index
(is (= -20 (order/time-score {:url "http://google.com"
:index 20}
{}
{}
{})))
; A score for a known URL equals its time value
(is (= 291 (order/time-score {:url "http://google.com"}
{(utils/url-key "http://google.com")
{:time 291}}
{}
{})))
; A score for a known URL gets added the time for its site
(is (= 468 (order/time-score {:url "http://google.com/somepage"}
{(utils/url-key "http://google.com") {:time 291}
(utils/url-key "http://google.com/somepage") {:time 345}}
{(utils/host-key "google.com") {:time 123}
(utils/host-key "apple.com") {:time 987}}
{})))
; A score for a known URL is not affected by the score of other URLs for the same site
(is (= 414 (order/time-score {:url "http://google.com/"}
{(utils/url-key "http://google.com") {:time 291}
(utils/url-key "http://google.com/somepage") {:time 345}}
{(utils/host-key "google.com") {:time 123}
(utils/host-key "apple.com") {:time 987}}
{})))
; A page inherits its site's score even if it's unknown
(is (= 987 (order/time-score {:url "http://apple.com/mac"}
{(utils/url-key "http://google.com") {:time 291}
(utils/url-key "http://google.com/somepage") {:time 345}}
{(utils/host-key "google.com") {:time 123}
(utils/host-key "apple.com") {:time 987}}
{})))
; A page inherits its site's score even if it's unknown, but substracts the index so
; that they are placed at the end.
(is (= 975 (order/time-score {:url "http://apple.com/mac" :index 12}
{(utils/url-key "http://google.com") {:time 291}
(utils/url-key "http://google.com/somepage") {:time 345}}
{(utils/host-key "google.com") {:time 123}
(utils/host-key "apple.com") {:time 987}}
{})))
; A page that has sound gets no extra score if the :sound-to-left? key isn't on settings
(is (= 291 (order/time-score {:url "http://google.com"
:audible true}
{(utils/url-key "http://google.com")
{:time 291}}
{}
{})))
; An audible page gets an extra score if the :sound-to-left? key is set to true on the settings,
; but based on the index, not the time spent
(is (= (+ 5 123 order/sound-extra-score)
(order/time-score {:url "http://google.com/translate"
:index 5
:audible true}
{(utils/url-key "http://google.com/translate")
{:time 456}}
{(utils/host-key "google.com") {:time 123}
(utils/host-key "apple.com") {:time 987}}
{:sound-to-left? true})))
; Non-http pages are penalized, but get a minimum score of 1 (they will
; likely have a time of 0 to begin with since they aren't tracked)
(is (= (* 124 order/non-http-penalty)
(order/time-score {:url "chrome://google.com/translate"
:index 5}
{}
{(utils/host-key "google.com") {:time 123}
(utils/host-key "apple.com") {:time 987}}
{}))))
(deftest test-score-tabs
(let [url-times {(utils/url-key "http://google.com") {:time 2910}
(utils/url-key "http://google.com/somepage") {:time 345}
(utils/url-key "http://apple.com/osx") {:time 10101}
(utils/url-key "http://apple.com/") {:time 2120}}
site-times {(utils/host-key "google.com") {:time 4295} ; Includes time from tabs which we have deleted
(utils/host-key "apple.com") {:time 12221}}]
; We have spent the longest at Apple, so it gets prioritized
; The extension tab ends up at the end because it's not http
(is (= [{:index 0 :id 23} {:index 1 :id 9} {:index 2 :id 1}]
(order/score-tabs [{:url "http://google.com"
:id 9
:index 15}
{:url "chrome://extensions/"
:id 1
:index 1}
{:url "https://apple.com/macbook"
:id 23
:index 912}]
url-times
site-times
{})))
; An unknown page ends up at the end
(is (= [{:index 0 :id 23} {:index 1 :id 9} {:index 2 :id 1} {:index 3 :id 2}]
(order/score-tabs [{:url "http://google.com"
:id 9
:index 15}
{:url "http://youtube.com/"
:id 2
:index 27}
{:url "chrome://extensions/"
:id 1
:index 1}
{:url "https://apple.com/macbook"
:id 23
:index 912}]
url-times
site-times
{})))
; Two unknown pages get sorted by their index order
(is (= [{:index 0 :id 23} {:index 1 :id 9} {:index 2 :id 1} {:index 3 :id 123} {:index 4 :id 2}]
(order/score-tabs [{:url "http://google.com"
:id 9
:index 15}
{:url "http://youtube.com/"
:id 2
:index 27}
{:url "http://vimeo.com/"
:id 123
:index 26}
{:url "chrome://extensions/"
:id 1
:index 1}
{:url "https://apple.com/macbook"
:id 23
:index 912}]
url-times
site-times
{})))
; An unknown page that is playing sound gets prioritized according to the settings
(is (= [{:index 0 :id 2} {:index 1 :id 23} {:index 2 :id 9} {:index 3 :id 1}]
(order/score-tabs [{:url "http://google.com"
:id 9
:index 15}
{:url "http://youtube.com/"
:id 2
:audible true
:index 27}
{:url "chrome://extensions/"
:id 1
:index 1}
{:url "https://apple.com/macbook"
:id 23
:index 912}]
url-times
site-times
{:sound-to-left? true})))
; If for any reason the Apple URL is not http, it gets de-prioritized
(is (= [{:index 0 :id 9} {:index 1 :id 1} {:index 2 :id 23}]
(order/score-tabs [{:url "http://google.com"
:id 9
:index 15}
{:url "chrome://extensions/"
:id 1
:index 1}
{:url "apple.com/macbook"
:id 23
:index 912}]
url-times
site-times
{})))
)
)
(ns relevance.test.runner
(:require [doo.runner :refer-macros [doo-tests]]
[relevance.test.order]
[relevance.test.data]
[relevance.test.migrations]
[relevance.test.utils]))
......@@ -8,7 +9,8 @@
(enable-console-print!)
(doo-tests 'relevance.test.data
(doo-tests 'relevance.test.order
'relevance.test.data
'relevance.test.migrations
'relevance.test.utils)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment