Commit Graph

22 Commits

Author SHA1 Message Date
Icaro Motta 60ad7c8a29
chore(tests): New match-strict? cljs.test directive (#20825)
Equality checks in tests using = give a bad experience by default on test
failures containing nested data structures. We use the cljs.test directive
match? from matcher-combinators library to help compare nested structures. The
problem with match? is that its default matcher for maps (embeds) can be too
permissive, and this causes surprises.

Here we upgrade matcher-combinators to latest, where a new matcher called
nested-equals is available. This matcher won't allow extra keys in maps. This
matcher eliminates the need for manually adding nested equals matchers as we
have to do currently.

- Upgrades matcher-combinators from 3.8.8 to 3.9.1 (latest as of 2024-07-19)

What changes?

When asserting in tests, we now have the option to use match-strict? or match?.
Both directives are available by integrating with cljs.test. The code
implementing the new match-strict? directive was 100% copied from the library
matcher-combinators because we need to wrap the expected value ourselves with
matcher-combinators.matchers/nested-equals. It's ugly code, but it's how we can
integrate with cljs.test/assert-expr.
2024-07-24 23:06:41 -03:00
Icaro Motta 615ad2f02b
dx(debug)_: Add FlowStorm, a tracing debugger for Clojure(Script) (#20054)
Adds FlowStorm https://github.com/flow-storm/flow-storm-debugger v3.7.5, a well
known (tracing) debugger for Clojure(Script).

With FlowStorm, you can debug almost any cljs function in status-mobile. And
although it is not as capable as on the JVM, its main features work well enough.

How do I use it? Please, check the markdown diff in this PR: doc/debugging.md.

When would you use FlowStorm in status-mobile? You can use it all the time if
you want, but FlowStorm can be a powerful tool to understand complex pieces of
code. Consider those large subscriptions or event handlers. Or all those
components with lots of bindings and calculations. Understanding some of these
things is no easy task, even with a REPL. It is not a replacement for re-frisk,
those are very different tools and each have their place.

Resources:

- Repository: https://github.com/flow-storm/flow-storm-debugger
- Documentation: https://flow-storm.github.io/flow-storm-debugger
- Features: https://github.com/flow-storm/flow-storm-debugger#features
- YouTube demos: https://github.com/flow-storm/flow-storm-debugger#some-demo-videos-newers-at-the-top
2024-06-03 19:47:10 -03:00
Icaro Motta 16398dfd55
Upgrade re-frame to latest (#19931)
Upgrade re-frame to latest, from v1.3.0 (released on
2022-08-27) to latest v1.4.3 (released on 2024-01-25).

Important changes:

- [Added] re-frame.alpha namespace, for testing proposed features (see flows
  (https://github.com/day8/re-frame/discussions/795) and polymorphic
  subscriptions https://github.com/day8/re-frame/issues/680#issuecomment-1676487563).
- [Added] dispatch-sync now emits a :sync trace to indicate when it has
  finished.
- Re-frame upgraded its dependency on Reagent to latest v1.2.0.
- There are two breaking changes in v1.4.0, but they don't affect us because we
  don't use interceptors path and unwrap.
2024-05-13 21:18:16 -03:00
Icaro Motta 52a6f5c17d
Upgrade clj-kondo to 2024.03.13 (#19930)
This PR upgrades clj-kondo (our Clojure linter) from v2023-09-07 to
v2024-03-13, so ~6 months of development updates.

You can check out the changes starting at
https://github.com/clj-kondo/clj-kondo/blob/master/CHANGELOG.md#20231020.
Nothing terribly useful to us this time, but as usual, clj-kondo can catch
more problems and more reliably than before.
2024-05-09 12:04:31 -03:00
Lungu Cristian f8cd14296f
Add Promesa to simplify working with promises (#18767)
* added promesa (clj)

Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>

* ref(resize): using promesa instead of passing cb

Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>

---------

Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>
2024-03-04 13:59:52 +02:00
Icaro Motta 563f1c588d
Improve test failure readability (#18049)
Problem: failed equality checks as in "(is (= expected actual))" will give a
single, long line of output that for anything but the simplest data structures
is unreadable by humans, and the output doesn't give a useful diff.

Solution: use library https://github.com/nubank/matcher-combinators and its test
directive "match?" which will pinpoint where two data structures differ. Then,
instead of "(is (= ...", use "(is (match? expected actual)". It works
beautifully.

The library offers other nice matchers, but the majority of the time match? is
sufficient.

Can we use another test runner like Kaocha? kaocha-cljs2
(https://github.com/lambdaisland/kaocha-cljs2) would be able to print better
test errors out of the box, among other features, but I have no clue if it would
work well or at all in our stack (in theory yes, but it's a larger piece of
work).
2023-12-05 17:20:54 -03:00
Icaro Motta c1dcd7a764
Introduce malli library (#17867)
This commit is the foundational step to start using malli
(https://github.com/metosin/malli) in this project.

Take in consideration we will only be able to realize malli's full power in
future iterations.

For those without context: the mobile team watched a presentation about malli
and went through a light RFC to put everyone on the same page, among other
discussions here and there in PRs.

To keep things relatively short:

1. Unit, integration and component tests will short-circuit (fail) when
   inputs/outputs don't conform to their respective function schemas (CI should
   fail too).
2. Failed schema checks will not block the app from initializing, nor throw an
   exception that would trigger the LogBox. Exceptions are only thrown in the
   scope of automated tests.
3. There's zero performance impact in production code because we only
   instrument. Instrumentation is removed from the compiled code due to the
   usage of "^boolean js.goog/DEBUG".
4. We shouldn't expect any meaningful slowdown during development.

**What are we instrumenting in this PR?**

Per our team's agreement, we're only instrumenting the bare minimum to showcase 2 examples.

- Instrument a utility function utils.money/format-amount using the macro
  approach.
- Instrument a quo component quo.components.counter.step.view/view using the
  functional approach.

Both approaches are useful, the functional approach is powerful and allow us to
instrument anonymous functions, like the ones we pass to subscriptions or event
handlers, or the higher-order function quo.theme/with-theme. The macro approach
is perfect for functions already defined with defn.

**I evaluated the schema or function in the REPL but nothing changes**

- If you evaluate the source function, you need to evaluate schema/=> or
  schema/instrument as well.
- Remember to *var quote* when using schema/instrument.
- You must call "(status-im2.setup.schema/setup!)" after any var is
  re-instrumented. It's advisable to add a keybinding in your editor to send
  this expression automatically to the CLJS REPL, or add the call at the end of
  the namespace you are working on (similar to how some devs add "(run-tests)"
  at the end of test namespaces).

**Where should schemas be defined?**

For the moment, we should focus on instrumenting quo components, so define each
function schema in the same namespace as the component's public "view" var.

To be specific:

- A schema used only to instrument a single function and not used elsewhere,
  like a quo component schema, wouldn't benefit from being defined in a separate
  namespace because that would force the developer to constantly open two files
  instead of one to check function signatures.
- A common schema reused across the repo, like ":schema.common/theme" should be
  registered in the global registry "schema.registry" so that consumers can just
  refer to it by keyword, as if it was a built-in malli schema.
- A common schema describing status-go entities like message, notification,
  community, etc can be stored either in the respective
  "src/status_im2/contexts/*" or registered globally, or even somewhere else.
  This is yet to be defined, but since I chose not to include schemas for them,
  we can postpone this guideline.
2023-11-18 11:04:48 -03:00
Icaro Motta ca6fd3df66
Upgrade Clojure libraries (#17690)
Upgrades and cleans up all production Clojure dependencies and 1 dev-only
dependency (com.taoensso/tufte).

- Remove warning "WARNING: update-keys already refers to:
  #'clojure.core/update-keys in namespace: io.aviso.exception"
- Remove hickory and mvxcvi/alphabase dependencies they are not used.
- Upgrade com.taoensso/tufte from 2.1.0 to 2.6.3
- Upgrade transit-cljs from 0.8.248 to 0.8.280
- Upgrade cljs-bean from 1.3.0 to 1.9.0
- Remove workaround for com.taoensso/timbre in shadow-cljs.edn
- Upgrade com.taoensso/timbre from 4.10 (Status fork) to 6.3.1
2023-10-20 20:47:23 -03:00
Icaro Motta 7f960f9be5
Add custom linter for i18n/label translation keywords (#17610)
This commit adds a custom linter to verify i18n/label is called with a qualified
keyword, like :t/foo. More sophisticated linters are possible too.

We also set the stage for other developers to consider more lint automation
instead of manually reviewing conventions in PRs.

If you want to understand how to write custom linters, check out
https://github.com/clj-kondo/clj-kondo/blob/master/doc/hooks.md. You can fire
the Clojure JVM REPL in status-mobile and play with the clj-kondo hook too, it
works beautifully.

Why do we care? By making sure all translation keywords are qualified with "t",
it is trivial to grep or replace them because they're unique in the repo, and
can't be confused with other words if you search by ":t/<something>".

Note: It's a best practice to commit clj-kondo configuration from external
libraries in the .clj-kondo directory. The directory .clj-kondo/babashka is
auto-generated, that's why it was added.
2023-10-11 18:53:34 -03:00
Icaro Motta b9890a9d44
Upgrade shadow-cljs and ClojureScript (#15417)
This commit upgrades Shadow CLJS from 2.11.16 (released on Feb/21) to latest
2.25.0 (Jul/23), so ~1.5 years worth of upgrades. By upgrading shadow we
can finally use the latest major Clojure version 1.11.x.

Why upgrade shadow?

- Shadow CLJS controls the ClojureScript version we can use. In order to use the
  latest major Clojure version we must upgrade Shadow CLJS.

- Shadow CLJS releases new versions very frequently, and if you take a look at
  its changelog https://github.com/thheller/shadow-cljs/blob/master/CHANGELOG.md, you'll see
  it had tons and tons of bug fixes over the years. I hope some of them help
  improve the DX for certain contributors who recently reported issues with
  it.

- Clojure 1.11 brings new features, bug fixes and even performance improvements
  (although I think the performance mostly impacts Clojure on the JVM). See the
  changelog https://github.com/clojure/clojure/blob/master/changes.md#changes-to-clojure-in-version-1110

Things that can be beneficial to us, or are interesting nonetheless:

- New :as-alias to be used in require, which is like :as but does not require
  the namespace to load. This means namespaced keywords using :as-alias can't
  cause circular dependency errors. This feature would very useful if we used
  namespaced keywords, but we don't, so...
  https://github.com/clojure/clojure/blob/master/changes.md#22-as-alias-in-require
- New macros run-test and run-test-var to run single test with fixtures and
  report.
- New iteration function, useful for processing paginated data.
  https://www.abhinavomprakash.com/posts/clojure-iteration/
- New update-keys function: applies a function to every key in a map.
- New update-vals function: applies a function to every value in a map.

Examples for update-vals and update-keys. They should perform better than the
common reduce-kv approach since they use a transient data structure.

    (let [m {:a 1 :b 2}]
      (update-vals m inc)) ; => {:a 2, :b 3}
    
    (let [m {:a 1 :b 2}]
      (update-keys m name)) ; => {"a" 1, "b" 2}

Why change namespaces within __tests__ directories?

Any namespace with the word --tests-- throws an error, like the one below. I
didn't bother investigating why, so I changed the guidelines to reflect the new
convention. It's probably related to the double dashes in the name.

    Namespace quo2.components.dividers.--tests--.divider-label-component-spec has a
    segment starting with an invalid JavaScript identifier at line 1
2023-07-28 13:40:54 -03:00
flexsurfer fb4d484d7d
bump reagent 1.2.0 (#16070) 2023-05-31 13:35:31 +02:00
Icaro Motta 9dad4716d6
Upgrade re-frame (#15997)
This commit upgrades re-frame to v1.3.0 (latest stable release), released ~9
months ago, in 2022-08-27. This is a solid upgrade, with no breaking changes as
far as I tested status-mobile. It's a great testament of re-frame's stability
and commitment to backwards compatibility, as are many Clojure libs.

Fixes https://github.com/status-im/status-mobile/issues/15963

The big, and truly relevant addition is the introduction of the :fx built-in
effect that was added ~3 years ago in Aug/2020 in v1.1.0.

Relevant changelog:

- Global interceptors are now supported (added in v1.0.0).
- reg-event-fx will just warn (not generate an error) if the effect map returned
  contains an unknown effect key.
- re-frame will now warn us when we are calling subscribe outside of a reactive
  context.
- "re-frame now guarantees that a :db effect, if present, will be actioned
  before any other sibling effects. re-frame continues to provide NO guarantees
  about the order in which other effects will be actioned."
  (https://day8.github.io/re-frame/releases/2020/#110-2020-08-24)
- There's syntactic sugar for trivial reg-sub declarations (added in v1.3.0).
  See the documentation for reg-sub for more details
  https://day8.github.io/re-frame/api-re-frame.core/#reg-sub
- "The built-in effect :dispatch-later can now take a single map value.
  Supplying a sequence of maps is now deprecated in favor of using multiple
  :dispatch-later effects within the new :fx effect."
  https://day8.github.io/re-frame/releases/2020/#111-2020-08-26
2023-05-31 06:08:34 -03:00
Alexander 27c8c5547c
[#14689] Link previews in chat (#14771)
* Initial

* Link fetching

* Post-merge fix
2023-01-18 22:43:26 +01:00
yqrashawn 39e29cfb5a
feat: replace clj-fmt with zprint (#14520) 2022-12-20 21:57:49 +08:00
Jakub Sokołowski 93f5b2e32c
nix: fix shadow-cljs on M1 by upgrading to 2.11.16
On M1 calling `shadow-cljs` fails with:
```
Execution error (UnsatisfiedLinkError) at java.lang.ClassLoader$NativeLibrary/load (ClassLoader.java:-2).
/private/var/folders/__/x311ykg17rqgq2wyl4kn1pdr0001yh/T/jna8753030888504535661.tmp:
    dlopen(/private/var/folders/__/x311ykg17rqgq2wyl4kn1pdr0001yh/T/jna8753030888504535661.tmp, 0x0001):
        tried: '/private/var/folders/__/x311ykg17rqgq2wyl4kn1pdr0001yh/T/jna8753030888504535661.tmp'
            (fat file, but missing compatible architecture (have (unknown,i386,x86_64), need (arm64e)))
```
This is due to an outdeted dependency on JNA 3.2.2, which is pulled in
by `hawk` package which up until release `2.11.16` was a `shadow-clj`
dependency which was removed because it was:

>Only used to be used on macOS since it was slightly faster than the default
>JVM implementation. However in Big Sur it seems to cause issues and break
>completely or just be a lot slower.

https://github.com/thheller/shadow-cljs/commit/f3b89b5a

Dropped the explicit dependency on `org.clojure/core.async` to avoid:
```
WARNING: The org.clojure/core.async dependency in shadow-cljs.edn was ignored.
Default version is used and override is not allowed to ensure compatibility.
```

Resolves: https://github.com/status-im/status-mobile/issues/14196

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2022-10-20 17:54:02 +02:00
Parvesh Monu 1047c26f69
Switcher and Bottom Tabs Animations and UI Performance Improvements
- Migrated Switcher animations to Reanimated V2
- Added bottom tabs & Stacks Animations
- Improved bottom tabs, tab changing performance
- Polished android & IOS UI
2022-06-28 23:51:24 +05:30
Jakub Sokołowski 293fd5fae1
nix: add missing cljfmt dependencies to nix/deps/clojure
It seems like this worked before purely because the `cljfmt` library was
already in the `~/.m2` cache folder. This issue was noticed when I
cleaned up the `~/.m2` folder on one Jenkins slave host and the Lint stage
started randomly failing.

Signed-off-by: Jakub Sokołowski <jakub@status.im>
Signed-off-by: andrey <motor4ik@gmail.com>
2021-03-01 16:42:38 +01:00
Jakub Sokołowski 37cf8ffe72
nix: update clojure dependencies
Signed-off-by: Jakub Sokołowski <jakub@status.im>
Signed-off-by: andrey <motor4ik@gmail.com>
2021-03-01 13:23:35 +01:00
Gheorghe Pinzaru 793579885a
Add universal QR scanner via common router
Rename events

Add router to handle all links

Use router in add new chat

Unify universal link and universal qr with router

Add icon for universal scanner

Update tests

Now routing is tested in routing PR

lint

Cleanup

QA fixes

Scan own profile

Handle more EIP

Fix wallet scanner

Fix stack for view profile in UL

Signed-off-by: Gheorghe Pinzaru <feross95@gmail.com>
2020-08-11 10:24:15 +03:00
Jakub Sokołowski 6746b7d932
nix: data in nix/deps/clojure should be JSON
Signed-off-by: Jakub Sokołowski <jakub@status.im>
2020-05-14 16:02:17 +02:00
Andrey Shovkoplyas d3860508ca
hot reload and re-frisk 1.3.1
Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
2020-05-04 11:22:19 +02:00
yenda d5ef218584
use shadow-cljs
Signed-off-by: Jakub Sokołowski <jakub@status.im>
Signed-off-by: yenda <eric@status.im>
2020-04-30 15:43:46 +02:00