first unit test

This commit is contained in:
Roman Volosovskyi 2016-05-29 21:14:34 +03:00
parent 043d28c44d
commit 1766b1af12
17 changed files with 145 additions and 98 deletions

5
.gitignore vendored
View File

@ -54,3 +54,8 @@ figwheel_server.log
# Lein
#
.lein-failures
## Doo
#
out
doo-index.html

View File

@ -8,7 +8,7 @@
[reagent "0.5.1" :exclusions [cljsjs/react]]
[re-frame "0.6.0"]
[prismatic/schema "1.0.4"]
^{:voom {:repo "git@github.com:status-im/status-lib.git"
^{:voom {:repo "git@github.com:status-im/status-lib.git"
:branch "master"}}
[status-im/protocol "0.1.1-20160525_083359-g53ab2c2"]
[natal-shell "0.1.6"]
@ -20,11 +20,12 @@
["do" "clean"
["with-profile" "prod" "cljsbuild" "once" "ios"]
["with-profile" "prod" "cljsbuild" "once" "android"]]}
:test-paths ["test/clj"]
:figwheel {:nrepl-port 7888}
:profiles {:dev {:dependencies [[figwheel-sidecar "0.5.0-2"]
[com.cemerick/piggieback "0.2.1"]
[io.appium/java-client "3.4.1"]
]
[io.appium/java-client "3.4.1"]]
:plugins [[lein-doo "0.1.6"]]
:source-paths ["src" "env/dev"]
:cljsbuild {:builds {:ios {:source-paths ["src" "env/dev"]
:figwheel true
@ -37,7 +38,13 @@
:compiler {:output-to "target/android/not-used.js"
:main "env.android.main"
:output-dir "target/android"
:optimizations :none}}}}
:optimizations :none}}
:test {:source-paths ["src" "test/cljs"]
:compiler
{:main status-im.test.runner
:output-to "target/test/test.js"
:optimizations :none
:target :nodejs}}}}
:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}
:prod {:cljsbuild {:builds {:ios {:source-paths ["src" "env/prod"]
:compiler {:output-to "index.ios.js"

View File

@ -60,5 +60,4 @@
(dispatch [:init-console-chat])
(dispatch [:init-chat])
(init-back-button-handler!)
;(.registerComponent app-registry "StatusIm" #(r/reactify-component app-root))
)
(.registerComponent app-registry "StatusIm" #(r/reactify-component app-root)))

View File

@ -2,18 +2,16 @@
(:require [clojure.string :as s]
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
[reagent.core :as r]
[status-im.components.react :refer [android?
view
text
image
navigator
toolbar-android
drawer-layout-android
touchable-opacity]]
[status-im.components.react :as re :refer [view
text
image
navigator
toolbar-android
drawer-layout-android
touchable-opacity]]
[status-im.resources :as res]
[status-im.components.drawer.styles :as st]
[status-im.i18n :refer [label]]
[status-im.components.react :refer [react]]))
[status-im.i18n :refer [label]]))
(defonce drawer-atom (atom))
@ -30,7 +28,7 @@
:style st/user-photo}])
(defn menu-item [{:keys [name handler]}]
[touchable-opacity {:style st/menu-item-touchable
[touchable-opacity {:style st/menu-item-touchable
:onPress (fn []
(close-drawer)
(handler))}
@ -41,40 +39,40 @@
(let [username (subscribe [:get :username])]
(fn []
[view st/drawer-menu
[view st/user-photo-container
[user-photo {}]]
[view st/name-container
[text {:style st/name-text}
@username]]
[view st/menu-items-container
[menu-item {:name (label :t/profile)
:handler #(dispatch [:navigate-to :my-profile])}]
[menu-item {:name (label :t/settings)
:handler (fn []
;; TODO not implemented
)}]
[menu-item {:name (label :t/discovery)
:handler #(dispatch [:navigate-to :discovery])}]
[menu-item {:name (label :t/contacts)
:handler #(dispatch [:show-contacts navigator])}]
[menu-item {:name (label :t/invite-friends)
:handler (fn []
;; TODO not implemented
)}]
[menu-item {:name (label :t/faq)
:handler (fn [])}]]
[view st/switch-users-container
[touchable-opacity {:onPress (fn []
(close-drawer)
;; TODO not implemented
)}
[text {:style st/switch-users-text}
(label :t/switch-users)]]]])))
[view st/user-photo-container
[user-photo {}]]
[view st/name-container
[text {:style st/name-text}
@username]]
[view st/menu-items-container
[menu-item {:name (label :t/profile)
:handler #(dispatch [:navigate-to :my-profile])}]
[menu-item {:name (label :t/settings)
:handler (fn []
;; TODO not implemented
)}]
[menu-item {:name (label :t/discovery)
:handler #(dispatch [:navigate-to :discovery])}]
[menu-item {:name (label :t/contacts)
:handler #(dispatch [:show-contacts navigator])}]
[menu-item {:name (label :t/invite-friends)
:handler (fn []
;; TODO not implemented
)}]
[menu-item {:name (label :t/faq)
:handler (fn [])}]]
[view st/switch-users-container
[touchable-opacity {:onPress (fn []
(close-drawer)
;; TODO not implemented
)}
[text {:style st/switch-users-text}
(label :t/switch-users)]]]])))
(defn drawer-view [items]
[drawer-layout-android {:drawerWidth 260
:drawerPosition react.DrawerLayoutAndroid.positions.Left
:drawerPosition re/react.DrawerLayoutAndroild.positions.Left
:render-navigation-view #(r/as-element [drawer-menu])
:ref (fn [drawer]
(reset! drawer-atom drawer))}
:ref (fn [drawer]
(reset! drawer-atom drawer))}
items])

View File

@ -1,29 +1,39 @@
(ns status-im.components.react
(:require [reagent.core :as r]
[status-im.components.styles :as st]))
[status-im.components.styles :as st]
[status-im.utils.utils :as u]))
(when (exists? js/window)
(set! js/window.React (js/require "react-native")))
(def react (js/require "react-native"))
(def react (u/require "react-native"))
(def app-registry (.-AppRegistry react))
(def navigator (r/adapt-react-class (.-Navigator react)))
(def text (r/adapt-react-class (.-Text react)))
(def view (r/adapt-react-class (.-View react)))
(def image (r/adapt-react-class (.-Image react)))
(def touchable-highlight-class (r/adapt-react-class (.-TouchableHighlight react)))
(defn get-react-property [name]
(aget react name))
(defn adapt-class [class]
(when class (r/adapt-react-class class)))
(defn get-class [name]
(adapt-class (get-react-property name)))
(def app-registry (get-react-property "AppRegistry"))
(def navigator (get-class "Navigator"))
(def text (get-class "Text"))
(def view (get-class "View"))
(def image (get-class "Image"))
(def touchable-highlight-class (get-class "TouchableHighlight"))
(defn touchable-highlight [props content]
[touchable-highlight-class
(merge {:underlay-color :transparent} props)
content])
(def toolbar-android (r/adapt-react-class (.-ToolbarAndroid react)))
(def list-view-class (r/adapt-react-class (.-ListView react)))
(def toolbar-android (get-class "ToolbarAndroid"))
(def list-view-class (get-class "ListView"))
(defn list-view [props]
[list-view-class (merge {:enableEmptySections true} props)])
(def scroll-view (r/adapt-react-class (.-ScrollView react)))
(def touchable-without-feedback (r/adapt-react-class (.-TouchableWithoutFeedback react)))
(def text-input-class (r/adapt-react-class (.-TextInput react)))
(def scroll-view (get-class "ScrollView"))
(def touchable-without-feedback (get-class "TouchableWithoutFeedback"))
(def text-input-class (get-class "TextInput"))
(defn text-input [props text]
[text-input-class (merge
{:underlineColorAndroid :transparent
@ -31,11 +41,13 @@
:placeholder "Type"}
props)
text])
(def drawer-layout-android (r/adapt-react-class (.-DrawerLayoutAndroid react)))
(def touchable-opacity (r/adapt-react-class (.-TouchableOpacity react)))
(def modal (r/adapt-react-class (.-Modal react)))
(def picker (r/adapt-react-class (.-Picker react)))
(def picker-item (r/adapt-react-class (.-Item (.-Picker react))))
(def drawer-layout-android (get-class "DrawerLayoutAndroid"))
(def touchable-opacity (get-class "TouchableOpacity"))
(def modal (get-class "Modal"))
(def picker (get-class "Picker"))
(def picker-item
(when-let [picker (get-react-property "Picker")]
(adapt-class (.-Item picker))))
(defn icon
@ -44,20 +56,18 @@
[image {:source {:uri (keyword (str "icon_" (name n)))}
:style style}]))
;(def react-linear-gradient (.-default (js/require "react-native-linear-gradient")))
;(def linear-gradient (r/adapt-react-class react-linear-gradient))
(def linear-gradient-class (js/require "react-native-linear-gradient"))
(def linear-gradient-class (u/require "react-native-linear-gradient"))
(defn linear-gradient [props]
(r/creacteElement linear-gradient-class
(r/create-element linear-gradient-class
(clj->js (merge {:inverted true} props))))
(def platform (.. react -Platform -OS))
(def platform
(when-let [pl (.-Platform react)] (.-OS pl)))
(def android? (= platform "android"))
(defn list-item [component]
(r/as-element component))
(def dismiss-keyboard! (js/require "dismissKeyboard"))
(def dismiss-keyboard! (u/require "dismissKeyboard"))

View File

@ -26,7 +26,7 @@
(register-handler :load-contacts load-contacts!)
;; TODO see https://github.com/rt2zz/react-native-contacts/issues/45
(def react-native-contacts (js/require "react-native-contacts"))
(def react-native-contacts #_(js/require "react-native-contacts"))
(defn contact-name [contact]
(->> contact

View File

@ -35,15 +35,19 @@
;; -- Common --------------------------------------------------------------
(defn set-el [db [_ k v]]
(assoc db k v))
(register-handler :set
(debug
(fn [db [_ k v]]
(assoc db k v))))
debug
set-el)
(defn set-in [db [_ path v]]
(assoc-in db path v))
(register-handler :set-in
(debug
(fn [db [_ path v]]
(assoc-in db path v))))
debug
set-in)
(register-handler :initialize-db
(fn [_ _]

View File

@ -1,12 +1,15 @@
(ns status-im.i18n
(:require
[status-im.translations.en :as en]))
[status-im.translations.en :as en]
[status-im.utils.utils :as u]))
(def i18n (js/require "react-native-i18n"))
(def i18n (u/require "react-native-i18n"))
(set! (.-fallbacks i18n) true)
(set! (.-defaultSeparator i18n) "/")
(set! (.-translations i18n) (clj->js {:en en/translations}))
(defn label [path & options]
(.t i18n (name path) (clj->js options)))
(if (exists? i18n.t)
(.t i18n (name path) (clj->js options))
(name path)))

View File

@ -2,7 +2,8 @@
(:require [cljs.reader :refer [read-string]]
[status-im.components.styles :refer [default-chat-color]]
[status-im.utils.logging :as log]
[status-im.utils.types :refer [to-string]])
[status-im.utils.types :refer [to-string]]
[status-im.utils.utils :as u])
(:refer-clojure :exclude [exists?]))
(def opts {:schema [{:name :contacts
@ -68,9 +69,10 @@
:objectType "tag"}
:last-updated "date"}}]})
(def realm-class (js/require "realm"))
(def realm-class (u/require "realm"))
(def realm (realm-class. (clj->js opts)))
(def realm (when (cljs.core/exists? js/window)
(realm-class. (clj->js opts))))
(def schema-by-name (->> (:schema opts)
(mapv (fn [{:keys [name] :as schema}]

View File

@ -1,9 +1,10 @@
(ns status-im.utils.crypt
(:require [goog.crypt :refer [byteArrayToHex]]
[clojure.string :as s])
[clojure.string :as s]
[status-im.utils.utils :as u])
(:import goog.crypt.Sha256))
(def random-bytes (js/require "react-native-randombytes"))
(def random-bytes (u/require "react-native-randombytes"))
(def sha-256 (Sha256.))
@ -19,7 +20,7 @@
(byteArrayToHex (.digest sha-256)))
(defn gen-random-bytes [length cb]
(.randomBytes random-bytes length (fn [& [err buf]]
#_(.randomBytes random-bytes length (fn [& [err buf]]
(if err
(cb {:error err})
(cb {:buffer buf})))))

View File

@ -1,16 +1,17 @@
(ns status-im.utils.phone-number)
(ns status-im.utils.phone-number
(:require [status-im.utils.utils :as u]))
(def i18n (js/require "react-native-i18n"))
(def locale (.-locale i18n))
(def i18n (u/require "react-native-i18n"))
(def locale (or (.-locale i18n) "___en"))
(def country-code (subs locale 3 5))
(set! js/PhoneNumber (js/require "awesome-phonenumber"))
(def awesome-phonenumber (u/require "awesome-phonenumber"))
;; todo check wrong numbers, .getNumber returns empty string
(defn format-phone-number [number]
(str (.getNumber (js/PhoneNumber. number country-code "international"))))
(str (.getNumber (awesome-phonenumber. number country-code "international"))))
(defn valid-mobile-number? [number]
(when (string? number)
(let [number-obj (js/PhoneNumber. number country-code "international")]
(let [number-obj (awesome-phonenumber. number country-code "international")]
(and (.isValid number-obj)
(.isMobile number-obj)))))

View File

@ -1,7 +1,8 @@
(ns status-im.utils.sms-listener
(:require [status-im.components.react :refer [android?]]))
(:require [status-im.components.react :refer [android?]]
[status-im.utils.utils :as u]))
(def sms-listener (.-default (js/require "react-native-android-sms-listener")))
(def sms-listener (.-default (u/require "react-native-android-sms-listener")))
;; Only android is supported!

View File

@ -5,6 +5,11 @@
[natal-shell.toast-android :as toast])
(:require [status-im.constants :as const]))
(defn require [module]
(if (exists? js/window)
(js/require module)
#js {}))
(defn log [obj]
(.log js/console obj))

View File

@ -0,0 +1,6 @@
(ns status-im.test.handlers
(:require [cljs.test :refer-macros [deftest is]]
[status-im.handlers :as h]))
(deftest test-set-val
(is (= {:key :val} (h/set-el {} [nil :key :val]))))

View File

@ -0,0 +1,5 @@
(ns status-im.test.runner
(:require [doo.runner :refer-macros [doo-tests]]
[status-im.test.handlers]))
(doo-tests 'status-im.test.handlers)