mirror of
https://github.com/status-im/status-lib.git
synced 2025-02-24 10:08:25 +00:00
abstract backend; add mock backend and testing (#57)
abstract backend; add mock backend and testing move bookmarks to backend wrapper move bookmarks to backend wrapper move bookmarks to backend wrapper working version cleanup add mock backend add nimble task & test folder add evn.sh make test run; implement bookmark method in the mock add nim unit test removing duplicated statement that was causing tests to run twice re-enable other initilizations in the status object; support specifying backend in the constructor update bookmark test update bookmark test update nimble and makefile update nimble and makefile update bookmarks test remove old browser file
This commit is contained in:
parent
bcc242a3cf
commit
5285cf7d8c
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
||||
nimcache
|
||||
vendor/.nimble
|
||||
/bottles/
|
||||
/test_nim/build
|
||||
|
9
Makefile
9
Makefile
@ -22,7 +22,8 @@ BUILD_SYSTEM_DIR := vendor/nimbus-build-system
|
||||
status-go \
|
||||
update \
|
||||
build_ctest \
|
||||
ctest
|
||||
ctest \
|
||||
test
|
||||
|
||||
ifeq ($(NIM_PARAMS),)
|
||||
# "variables.mk" was not included, so we update the submodules.
|
||||
@ -64,7 +65,6 @@ else
|
||||
LIBSTATUS_EXT := so
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(detected_OS),Darwin)
|
||||
bottles/openssl:
|
||||
./scripts/fetch-brew-bottle.sh openssl
|
||||
@ -97,7 +97,9 @@ NIM_PARAMS += --outdir:./build
|
||||
|
||||
STATUSGO := vendor/status-go/build/bin/libstatus.$(LIBSTATUS_EXT)
|
||||
STATUSGO_LIBDIR := $(shell pwd)/$(shell dirname "$(STATUSGO)")
|
||||
export STATUSGO
|
||||
export STATUSGO_LIBDIR
|
||||
export LIBSTATUS_EXT
|
||||
|
||||
status-go: $(STATUSGO)
|
||||
$(STATUSGO): | deps
|
||||
@ -128,4 +130,7 @@ ctest: | build_ctest
|
||||
clean: | clean-common
|
||||
rm -rf bin/* node_modules bottles/* pkg/* tmp/* $(STATUSGO)
|
||||
|
||||
test:
|
||||
$(ENV_SCRIPT) nimble tests
|
||||
|
||||
endif # "variables.mk" was not included
|
||||
|
31
backends/backend.nim
Normal file
31
backends/backend.nim
Normal file
@ -0,0 +1,31 @@
|
||||
import backend_type
|
||||
|
||||
import backend_wrapper
|
||||
export backend_wrapper
|
||||
|
||||
from statusgo/types as statusgo_types import StatusGoBackend
|
||||
from mock/types as mock_types import MockBackend
|
||||
export StatusGoBackend
|
||||
export MockBackend
|
||||
|
||||
import base/bookmarks
|
||||
|
||||
import statusgo/statusgo_instance
|
||||
export newStatusGoBackendInstance
|
||||
|
||||
import mock/mock_instance
|
||||
export newMockBackendInstance
|
||||
|
||||
import statusgo/bookmark as statusgo_bookmark
|
||||
import mock/bookmark as mock_bookmark
|
||||
|
||||
from bookmarks as bookmarks_methods import storeBookmark, updateBookmark, getBookmarks, deleteBookmark
|
||||
export storeBookmark, updateBookmark, getBookmarks, deleteBookmark
|
||||
|
||||
method loadBackend*(self: BackendWrapper, name: string) =
|
||||
if name == "statusgo":
|
||||
self.backend = newStatusGoBackendInstance()
|
||||
if name == "mock":
|
||||
self.backend = newMockBackendInstance()
|
||||
else:
|
||||
raise newException(ValueError, "unknown backend")
|
1
backends/backend_type.nim
Normal file
1
backends/backend_type.nim
Normal file
@ -0,0 +1 @@
|
||||
type Backend* = ref object of RootObj
|
7
backends/backend_wrapper.nim
Normal file
7
backends/backend_wrapper.nim
Normal file
@ -0,0 +1,7 @@
|
||||
import backend_type
|
||||
|
||||
type BackendWrapper* = ref object
|
||||
backend*: Backend
|
||||
|
||||
proc newBackendWrapperInstance*(): BackendWrapper =
|
||||
result = BackendWrapper()
|
14
backends/base/bookmarks.nim
Normal file
14
backends/base/bookmarks.nim
Normal file
@ -0,0 +1,14 @@
|
||||
import ../../types/[bookmark]
|
||||
import ../backend_type
|
||||
|
||||
method storeBookmark*(self: Backend, bookmark: Bookmark): Bookmark =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method updateBookmark*(self: Backend, originalUrl: string, bookmark: Bookmark) =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getBookmarks*(self: Backend): seq[Bookmark] =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method deleteBookmark*(self: Backend, url: string) =
|
||||
raise newException(ValueError, "No implementation available")
|
2
backends/base/main.nim
Normal file
2
backends/base/main.nim
Normal file
@ -0,0 +1,2 @@
|
||||
import bookmark
|
||||
export bookmark
|
15
backends/bookmarks.nim
Normal file
15
backends/bookmarks.nim
Normal file
@ -0,0 +1,15 @@
|
||||
import backend_type, backend_wrapper
|
||||
import base/bookmarks
|
||||
import ../types/[bookmark]
|
||||
|
||||
proc storeBookmark*(self: BackendWrapper, bookmark: Bookmark): Bookmark =
|
||||
self.backend.storeBookmark(bookmark)
|
||||
|
||||
proc updateBookmark*(self: BackendWrapper, originalUrl: string, bookmark: Bookmark) =
|
||||
self.backend.updateBookmark(originalUrl, bookmark)
|
||||
|
||||
proc getBookmarks*(self: BackendWrapper): seq[Bookmark] =
|
||||
self.backend.getBookmarks()
|
||||
|
||||
proc deleteBookmark*(self: BackendWrapper, url: string) =
|
||||
self.backend.deleteBookmark(url)
|
23
backends/mock/bookmark.nim
Normal file
23
backends/mock/bookmark.nim
Normal file
@ -0,0 +1,23 @@
|
||||
import tables, sequtils
|
||||
import types
|
||||
import ../../types/[bookmark], json, chronicles
|
||||
import ../backend_type
|
||||
|
||||
var bookmarks_storage_mock = initTable[string, Bookmark]()
|
||||
|
||||
method storeBookmark*(self: MockBackend, bookmark: Bookmark): Bookmark =
|
||||
result = bookmark
|
||||
bookmarks_storage_mock[bookmark.url] = bookmark
|
||||
|
||||
method updateBookmark*(self: MockBackend, originalUrl: string, bookmark: Bookmark) =
|
||||
bookmarks_storage_mock.del(originalUrl)
|
||||
bookmarks_storage_mock[bookmark.url] = bookmark
|
||||
|
||||
method getBookmarks*(self: MockBackend): seq[Bookmark] =
|
||||
var bookmarks: seq[Bookmark] = @[]
|
||||
for b in bookmarks_storage_mock.values:
|
||||
bookmarks.add(b)
|
||||
result = bookmarks
|
||||
|
||||
method deleteBookmark*(self: MockBackend, url: string) =
|
||||
bookmarks_storage_mock.del(url)
|
8
backends/mock/main.nim
Normal file
8
backends/mock/main.nim
Normal file
@ -0,0 +1,8 @@
|
||||
import types
|
||||
|
||||
proc newMockBackendInstance*(): MockBackend =
|
||||
result = MockBackend()
|
||||
|
||||
export types
|
||||
# import bookmark
|
||||
# export bookmark
|
5
backends/mock/mock_instance.nim
Normal file
5
backends/mock/mock_instance.nim
Normal file
@ -0,0 +1,5 @@
|
||||
import types
|
||||
|
||||
proc newMockBackendInstance*(): MockBackend =
|
||||
result = MockBackend()
|
||||
|
3
backends/mock/types.nim
Normal file
3
backends/mock/types.nim
Normal file
@ -0,0 +1,3 @@
|
||||
import ../backend_type
|
||||
|
||||
type MockBackend* = ref object of Backend
|
@ -1,6 +1,6 @@
|
||||
import json, chronicles
|
||||
import core
|
||||
import ../types/[bookmark]
|
||||
import types
|
||||
import core, ../../types/[bookmark], json, chronicles
|
||||
import ../backend_type
|
||||
|
||||
proc storeBookmark*(bookmark: Bookmark): Bookmark =
|
||||
let payload = %* [{"url": bookmark.url, "name": bookmark.name}]
|
58
backends/statusgo/core.nim
Normal file
58
backends/statusgo/core.nim
Normal file
@ -0,0 +1,58 @@
|
||||
import json, nimcrypto, chronicles
|
||||
import status_go, ../../status/utils
|
||||
|
||||
logScope:
|
||||
topics = "rpc"
|
||||
|
||||
proc callRPC*(inputJSON: string): string =
|
||||
return $status_go.callRPC(inputJSON)
|
||||
|
||||
proc callPrivateRPCRaw*(inputJSON: string): string =
|
||||
return $status_go.callPrivateRPC(inputJSON)
|
||||
|
||||
proc callPrivateRPC*(methodName: string, payload = %* []): string =
|
||||
try:
|
||||
let inputJSON = %* {
|
||||
"jsonrpc": "2.0",
|
||||
"method": methodName,
|
||||
"params": %payload
|
||||
}
|
||||
debug "callPrivateRPC", rpc_method=methodName
|
||||
let response = status_go.callPrivateRPC($inputJSON)
|
||||
result = $response
|
||||
if parseJSON(result).hasKey("error"):
|
||||
error "rpc response error", result, payload, methodName
|
||||
except Exception as e:
|
||||
error "error doing rpc request", methodName = methodName, exception=e.msg
|
||||
|
||||
# proc sendTransaction*(inputJSON: string, password: string): string =
|
||||
# var hashed_password = "0x" & $keccak_256.digest(password)
|
||||
# return $status_go.sendTransaction(inputJSON, hashed_password)
|
||||
|
||||
# proc startMessenger*() =
|
||||
# discard callPrivateRPC("startMessenger".prefix)
|
||||
|
||||
# proc addPeer*(peer: string) =
|
||||
# discard callPrivateRPC("admin_addPeer", %* [peer])
|
||||
|
||||
# proc removePeer*(peer: string) =
|
||||
# discard callPrivateRPC("admin_removePeer", %* [peer])
|
||||
|
||||
# proc markTrustedPeer*(peer: string) =
|
||||
# discard callPrivateRPC("markTrustedPeer".prefix(false), %* [peer])
|
||||
|
||||
# proc getBlockByNumber*(blockNumber: string): string =
|
||||
# result = callPrivateRPC("eth_getBlockByNumber", %* [blockNumber, false])
|
||||
|
||||
# proc getTransfersByAddress*(address: string, toBlock: string, limit: string, fetchMore: bool = false): string =
|
||||
# let toBlockParsed = if not fetchMore: newJNull() else: %toBlock
|
||||
# result = callPrivateRPC("wallet_getTransfersByAddress", %* [address, toBlockParsed, limit, fetchMore])
|
||||
|
||||
# proc signMessage*(rpcParams: string): string =
|
||||
# return $status_go.signMessage(rpcParams)
|
||||
|
||||
# proc signTypedData*(data: string, address: string, password: string): string =
|
||||
# return $status_go.signTypedData(data, address, password)
|
||||
|
||||
# proc getBloomFilter*(): string =
|
||||
# return $callPrivateRPC("bloomFilter".prefix, %* []).parseJSON()["result"].getStr
|
8
backends/statusgo/main.nim
Normal file
8
backends/statusgo/main.nim
Normal file
@ -0,0 +1,8 @@
|
||||
import types
|
||||
|
||||
proc newStatusGoBackendInstance*(): StatusGoBackend =
|
||||
result = StatusGoBackend()
|
||||
|
||||
export types
|
||||
import bookmark
|
||||
export bookmark
|
4
backends/statusgo/statusgo_instance.nim
Normal file
4
backends/statusgo/statusgo_instance.nim
Normal file
@ -0,0 +1,4 @@
|
||||
import types
|
||||
|
||||
proc newStatusGoBackendInstance*(): StatusGoBackend =
|
||||
result = StatusGoBackend()
|
3
backends/statusgo/types.nim
Normal file
3
backends/statusgo/types.nim
Normal file
@ -0,0 +1,3 @@
|
||||
import ../backend_type
|
||||
|
||||
type StatusGoBackend* = ref object of Backend
|
7
env.sh
Executable file
7
env.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# We use ${BASH_SOURCE[0]} instead of $0 to allow sourcing this file
|
||||
# and we fall back to a Zsh-specific special var to also support Zsh.
|
||||
REL_PATH="$(dirname ${BASH_SOURCE[0]:-${(%):-%x}})"
|
||||
ABS_PATH="$(cd ${REL_PATH}; pwd)"
|
||||
source ${ABS_PATH}/vendor/nimbus-build-system/scripts/env.sh
|
@ -7,3 +7,46 @@ license = "MIT"
|
||||
skipDirs = @["test"]
|
||||
|
||||
requires "nim >= 1.2.0"
|
||||
|
||||
import strutils
|
||||
|
||||
const release_opts =
|
||||
" --define:danger" &
|
||||
" --define:strip" &
|
||||
" --hints:off" &
|
||||
" --opt:size" &
|
||||
" --passC:-flto" &
|
||||
" --passL:-flto"
|
||||
|
||||
const debug_opts =
|
||||
" --debugger:native" &
|
||||
" --define:chronicles_line_numbers" &
|
||||
" --define:debug" &
|
||||
" --linetrace:on" &
|
||||
" --stacktrace:on"
|
||||
|
||||
proc buildAndRun(name: string,
|
||||
srcDir = "test_nim/",
|
||||
outDir = "test_nim/build/",
|
||||
params = "",
|
||||
cmdParams = "",
|
||||
lang = "c") =
|
||||
mkDir outDir
|
||||
exec "nim " &
|
||||
lang &
|
||||
(if getEnv("RELEASE").strip != "false": release_opts else: debug_opts) &
|
||||
" --define:ssl" &
|
||||
" --passL:" & getEnv("STATUSGO") & "" &
|
||||
# " --passL:" & "vendor/status-go/build/bin/libstatus.dylib" & "" &
|
||||
" --out:" & outDir & name &
|
||||
" " &
|
||||
srcDir & name & ".nim"
|
||||
if defined(macosx):
|
||||
exec "install_name_tool -add_rpath " & getEnv("STATUSGO_LIBDIR") & " " & outDir & name
|
||||
exec "install_name_tool -change " & "libstatus." & getEnv("LIBSTATUS_EXT") & " @rpath/libstatus." & getEnv("LIBSTATUS_EXT") & " " & outDir & name
|
||||
if getEnv("RUN_AFTER_BUILD").strip != "false":
|
||||
exec outDir & name
|
||||
|
||||
task tests, "Build and run all tests":
|
||||
rmDir "test_nim/build/"
|
||||
buildAndRun "test_all"
|
||||
|
@ -1,23 +1,28 @@
|
||||
import statusgo_backend/browser as status_browser
|
||||
# import statusgo_backend/browser as status_browser
|
||||
import ../eventemitter
|
||||
import ./types/[bookmark]
|
||||
|
||||
import ../types/[bookmark]
|
||||
|
||||
import ../backends/backend
|
||||
|
||||
type
|
||||
BrowserModel* = ref object
|
||||
events*: EventEmitter
|
||||
backend*: BackendWrapper
|
||||
|
||||
proc newBrowserModel*(events: EventEmitter): BrowserModel =
|
||||
proc newBrowserModel*(events: EventEmitter, backend: BackendWrapper): BrowserModel =
|
||||
result = BrowserModel()
|
||||
result.events = events
|
||||
result.backend = backend
|
||||
|
||||
proc storeBookmark*(self: BrowserModel, bookmark: Bookmark): Bookmark =
|
||||
return status_browser.storeBookmark(bookmark)
|
||||
return self.backend.storeBookmark(bookmark)
|
||||
|
||||
proc updateBookmark*(self: BrowserModel, originalUrl: string, bookmark: Bookmark) =
|
||||
status_browser.updateBookmark(originalUrl, bookmark)
|
||||
self.backend.updateBookmark(originalUrl, bookmark)
|
||||
|
||||
proc getBookmarks*(self: BrowserModel): seq[Bookmark] =
|
||||
result = status_browser.getBookmarks()
|
||||
result = self.backend.getBookmarks()
|
||||
|
||||
proc deleteBookmark*(self: BrowserModel, url: string) =
|
||||
status_browser.deleteBookmark(url)
|
||||
self.backend.deleteBookmark(url)
|
||||
|
@ -7,9 +7,12 @@ import ../eventemitter
|
||||
import bitops, stew/byteutils, chronicles
|
||||
import ./types/[setting]
|
||||
|
||||
import ../backends/backend
|
||||
|
||||
export chat, accounts, node, messages, contacts, profile, network, permissions, fleet, eventemitter
|
||||
|
||||
type Status* = ref object
|
||||
backend*: BackendWrapper
|
||||
events*: EventEmitter
|
||||
fleet*: FleetModel
|
||||
chat*: ChatModel
|
||||
@ -30,8 +33,10 @@ type Status* = ref object
|
||||
provider*: ProviderModel
|
||||
osnotifications*: OsNotifications
|
||||
|
||||
proc newStatusInstance*(fleetConfig: string): Status =
|
||||
proc newStatusInstance*(fleetConfig: string, backendName:string = "statusgo"): Status =
|
||||
result = Status()
|
||||
result.backend = newBackendWrapperInstance()
|
||||
result.backend.loadBackend(backendName)
|
||||
result.events = createEventEmitter()
|
||||
result.fleet = fleet.newFleetModel(fleetConfig)
|
||||
result.chat = chat.newChatModel(result.events)
|
||||
@ -48,7 +53,7 @@ proc newStatusInstance*(fleetConfig: string): Status =
|
||||
result.permissions = permissions.newPermissionsModel(result.events)
|
||||
result.settings = settings.newSettingsModel(result.events)
|
||||
result.mailservers = mailservers.newMailserversModel(result.events)
|
||||
result.browser = browser.newBrowserModel(result.events)
|
||||
result.browser = browser.newBrowserModel(result.events, result.backend)
|
||||
result.tokens = tokens.newTokensModel(result.events)
|
||||
result.provider = provider.newProviderModel(result.events, result.permissions, result.wallet)
|
||||
result.osnotifications = newOsNotifications(result.events)
|
||||
|
@ -221,6 +221,6 @@ proc onAsyncFetchCryptoServices*(self: Wallet2Model, response: string) =
|
||||
|
||||
self.events.emit("wallet2_cryptoServicesFetched", CryptoServicesArg(services: responseArray))
|
||||
|
||||
proc toggleNetwork*(self: StatusWalletController, network: Network) =
|
||||
proc toggleNetwork*(self: Wallet2Model, network: Network) =
|
||||
network.enabled = not network.enabled
|
||||
status_network.upsertNetwork(network)
|
||||
status_network.upsertNetwork(network)
|
||||
|
49
test_nim/bookmarks.nim
Normal file
49
test_nim/bookmarks.nim
Normal file
@ -0,0 +1,49 @@
|
||||
import # std libs
|
||||
std/[json, options, os, unittest]
|
||||
|
||||
import ../status/status
|
||||
import ../status/browser
|
||||
import ../types/[bookmark]
|
||||
|
||||
suite "#Bookmarks":
|
||||
setup:
|
||||
let fleetConfig = "{\"fleets\":{\"eth.prod\":{\"boot\":{\"boot-01.ac-cn-hongkong-c.eth.prod\":\"enode://6e6554fb3034b211398fcd0f0082cbb6bd13619e1a7e76ba66e1809aaa0c5f1ac53c9ae79cf2fd4a7bacb10d12010899b370c75fed19b991d9c0cdd02891abad@47.75.99.169:443\"},\"mail\":{\"mail-01.ac-cn-hongkong-c.eth.prod\":\"enode://606ae04a71e5db868a722c77a21c8244ae38f1bd6e81687cc6cfe88a3063fa1c245692232f64f45bd5408fed5133eab8ed78049332b04f9c110eac7f71c1b429@47.75.247.214:443\"},\"rendezvous\":{\"boot-01.ac-cn-hongkong-c.eth.prod\":\"/ip4/47.75.99.169/tcp/30703/ethv4/16Uiu2HAmV8Hq9e3zm9TMVP4zrVHo3BjqW5D6bDVV6VQntQd687e4\"},\"whisper\":{\"node-01.ac-cn-hongkong-c.eth.prod\":\"enode://b957e51f41e4abab8382e1ea7229e88c6e18f34672694c6eae389eac22dab8655622bbd4a08192c321416b9becffaab11c8e2b7a5d0813b922aa128b82990dab@47.75.222.178:443\"}}},\"meta\":{\"hostname\":\"node-01.do-ams3.proxy.misc\",\"timestamp\":\"2021-09-09T00:00:14.760436\"}}";
|
||||
let statuslib_instance = newStatusInstance(fleetConfig, "mock")
|
||||
|
||||
test "storeBookmark: should store a bookmark":
|
||||
let new_bookmark = Bookmark(name: "status", url: "https://status.im")
|
||||
let returned_bookmark = statuslib_instance.browser.storeBookmark(new_bookmark)
|
||||
check(returned_bookmark.name == "status")
|
||||
check(returned_bookmark.url == "https://status.im")
|
||||
let stored_bookmarks = statuslib_instance.browser.getBookmarks()
|
||||
check(stored_bookmarks[0].name == "status")
|
||||
check(stored_bookmarks[0].url == "https://status.im")
|
||||
|
||||
test "getBookmarks: should get list of stored bookmarks":
|
||||
let new_bookmark = Bookmark(name: "status2", url: "https://status2.im")
|
||||
let returned_bookmark = statuslib_instance.browser.storeBookmark(new_bookmark)
|
||||
check(returned_bookmark.name == "status2")
|
||||
check(returned_bookmark.url == "https://status2.im")
|
||||
let stored_bookmarks = statuslib_instance.browser.getBookmarks()
|
||||
check(stored_bookmarks.len == 2)
|
||||
check(stored_bookmarks[0].name == "status")
|
||||
check(stored_bookmarks[0].url == "https://status.im")
|
||||
check(stored_bookmarks[1].name == "status2")
|
||||
check(stored_bookmarks[1].url == "https://status2.im")
|
||||
|
||||
test "deleteBookmark: should delete an existing bookmark":
|
||||
statuslib_instance.browser.deleteBookmark("https://status.im")
|
||||
|
||||
let stored_bookmarks = statuslib_instance.browser.getBookmarks()
|
||||
check(stored_bookmarks.len == 1)
|
||||
check(stored_bookmarks[0].name == "status2")
|
||||
check(stored_bookmarks[0].url == "https://status2.im")
|
||||
|
||||
test "updateBookmark: should update an existing bookmark":
|
||||
let new_bookmark = Bookmark(name: "status3", url: "https://status3.im")
|
||||
statuslib_instance.browser.updateBookmark("https://status2.im", new_bookmark)
|
||||
|
||||
let stored_bookmarks = statuslib_instance.browser.getBookmarks()
|
||||
check(stored_bookmarks.len == 1)
|
||||
check(stored_bookmarks[0].name == "status3")
|
||||
check(stored_bookmarks[0].url == "https://status3.im")
|
2
test_nim/test_all.nim
Normal file
2
test_nim/test_all.nim
Normal file
@ -0,0 +1,2 @@
|
||||
import
|
||||
./bookmarks
|
@ -1,7 +1,5 @@
|
||||
{.used.}
|
||||
|
||||
type Bookmark* = ref object
|
||||
name*: string
|
||||
url*: string
|
||||
imageUrl*: string
|
||||
|
Loading…
x
Reference in New Issue
Block a user