Mateus Felipe

Today I Learned

Rust Box

What is the "Box" in Rust Lang

rustboxmemoryheapstack

Reading some Rust code examples in documentation and blogs, I can see the use of Box<T> declaration. Like:

struct Schema {
    commands: Vec<Box<dyn Migration>>,
}
struct Schema {
    commands: Vec<Box<dyn Migration>>,
}

According to the official Rust documentation: "All values in Rust are stack allocated by default. Values can be boxed (allocated on the heap) by creating a Box<T>. A box is a smart pointer to a heap allocated value of type T. When a box goes out of scope, its destructor is called, the inner object is destroyed, and the memory on the heap is freed."

ref: https://doc.rust-lang.org

Handshake Combinations

Math behind the calculation of the number of handshakes from N persons

mathmatemáticaformulacombinationscombinatória

Given nn people, how many handshakes will be given by all the people greeting each other?

We can determine this using the formula:

n(n1)2\frac{n(n-1)}{2}

Where nn is the number of people that will handshake.

ref: solution for https://www.hackerrank.com/challenges/handshake/problem

Disable Node Warnings

How to disable node warnings with env variable

nodewarningsincovenience

When we run a node script, we can see incovenie warnings like:

(node:3174) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
(node:3174) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)

For disable this warnings, just pass NODE_NO_WARNINGS=1 as environment variable before node command or script, e.g.:

NODE_NO_WARNINGS=1 node index.js
NODE_NO_WARNINGS=1 node index.js

On package.json script:

// ...
  "script": {
    "test": "NODE_NO_WARNINGS=1 jest --watch"
  }
// ...
// ...
  "script": {
    "test": "NODE_NO_WARNINGS=1 jest --watch"
  }
// ...

Position Sticky

Use position sticky with tailwindcss

tailwindcsscssui

We can use sticky class when using tailwind to make an element fixed on screen while the parent element is visible.

Code:

<div class="relative">
  <h1 class="sticky top-0">Element</h1>
</div>
<div class="relative">
  <h1 class="sticky top-0">Element</h1>
</div>

CSS Equivalent:

.parent-element {
  position: relative;
}
.element {
  position: sticky;
  top: 0;
}
.parent-element {
  position: relative;
}
.element {
  position: sticky;
  top: 0;
}

Visual example: https://www.w3schools.com/howto/howto_css_sticky_element.asp

Mock module inside test

How to mock module implementation inside a test with jest

reactnext.jstestsjestzustandreact-testing-librarymock

Sometimes you are testing a component and need to mock a module (in this case I needed to mock a zustand store), but with the exemple of "next/navigation" mock, you are mocking the module for entire test suit on the file that you declare the jest.mock(). But, if you want to mock a specific implementation for each test? So first, with need to declare the module mock, without pass the implementation function:

jest.mock('../../stores/sounds-state-store')
jest.mock('../../stores/sounds-state-store')

In this case we are mocking "../../stores/sounds-state-store" module

And, inside each test, we will use the jest.Mock.mockImplementation() function to mock the implementation of module inside it/test scope:

the store we want to mock is useSoundsStateStore, from '../../stores/sounds-state-store'

useSoundsStateStore.mockImplementation(
  () =>
    [{ active: true, id: 'd4ad48e', loaded: true, volume: 1 }] as SoundState[]
)
useSoundsStateStore.mockImplementation(
  () =>
    [{ active: true, id: 'd4ad48e', loaded: true, volume: 1 }] as SoundState[]
)

Full code:

// other imports...
import { SoundState, useSoundsStateStore } from '../../stores/sounds-state-store'
 
jest.mock('../../stores/sounds-state-store')
 
describe('Clear Button', () => {
  // tests...
 
  it('should not be disabled', async () => {
    ;(useSoundsStateStore as unknown as jest.Mock).mockImplementation(
      () =>
        [
          { active: true, id: 'd4ad48e', loaded: true, volume: 1 }
        ] as SoundState[]
    )
 
    render(<ClearButton />)
 
    const button = await screen.findByRole('button', { name: /clear/i })
 
    expect(button.getAttribute('disabled')).toBeNull()
  })
 
  // tests...
})
// other imports...
import { SoundState, useSoundsStateStore } from '../../stores/sounds-state-store'
 
jest.mock('../../stores/sounds-state-store')
 
describe('Clear Button', () => {
  // tests...
 
  it('should not be disabled', async () => {
    ;(useSoundsStateStore as unknown as jest.Mock).mockImplementation(
      () =>
        [
          { active: true, id: 'd4ad48e', loaded: true, volume: 1 }
        ] as SoundState[]
    )
 
    render(<ClearButton />)
 
    const button = await screen.findByRole('button', { name: /clear/i })
 
    expect(button.getAttribute('disabled')).toBeNull()
  })
 
  // tests...
})

Note that we use:

;(useSoundsStateStore as unknown as jest.Mock).mockImplementation()
;(useSoundsStateStore as unknown as jest.Mock).mockImplementation()

instead of:

useSoundsStateStore.mockImplementation()
useSoundsStateStore.mockImplementation()

Because it's a typescript project, and we need to tell the ts compiler that useSoundsStateStore have jest.Mock functions on this scope.

references:

Mock "next/navigation" with Jest

How to fix error "invariant expected app router to be mounted" when test Next.js hooks/components

reactnext.jstestsjestreact-testing-librarymocknext/navigation

Next.js: 14.0.3

When you try to test a component or hook that uses some function from "next/navigation" module (like useRouter, useSearchParams, useSearchParams, etc.), you may come across the error:

● Test suite failed to run
 
  invariant expected app router to be mounted
 
    5 |
    6 | export default function useQueryState(key: string, defaultValue: string = '') {
  > 7 |   const router = useRouter()
      |                           ^
    8 |   const searchParams = useSearchParams()
    9 |   const pathname = usePathname()
   10 |
● Test suite failed to run
 
  invariant expected app router to be mounted
 
    5 |
    6 | export default function useQueryState(key: string, defaultValue: string = '') {
  > 7 |   const router = useRouter()
      |                           ^
    8 |   const searchParams = useSearchParams()
    9 |   const pathname = usePathname()
   10 |

This happening because the "next/navigation" just works when app router was monted, to solve this, you need to mock the entire module. Put this before all your describes and it/tests:

jest.mock('next/navigation', () => ({
  useRouter: jest.fn(() => ({
    replace: jest.fn()
  })),
  useSearchParams: jest.fn(() => ({
    get: jest.fn()
  })),
  usePathname: jest.fn()
}))
jest.mock('next/navigation', () => ({
  useRouter: jest.fn(() => ({
    replace: jest.fn()
  })),
  useSearchParams: jest.fn(() => ({
    get: jest.fn()
  })),
  usePathname: jest.fn()
}))

references: https://github.com/vercel/next.js/discussions/48937