Third party library mocked with Jest still tries to access internals
cross-posted from: https://programming.dev/post/12974961
> I have a function as such:
>
> typescript > export type SendMessageParams = { > chatSession?: ChatSession, > // ... other params ... > }; > > const sendMessage = async ({ > chatSession, > // ... other params ... > }: SendMessageParams): Promise<void> => { > // await chatSession?.sendMessage() > // somewhere in implementation > }; > > export default sendMessage; >
>
> ChatSession is from @google/generative-ai
.
>
> I'd like to mock it in my test file as such:
>
> typescript > let defaultParams: SendMessageParams; > > beforeEach(() => { > jest.mock('@google/generative-ai', () => ({ > ChatSession: { > sendMessage: async (content: string) => content, > }, > })); > defaultParams = { > chatSession: new ChatSession('', ''), > // ... other params ... > }; > }); > > afterEach(() => { > jest.clearAllMocks(); > }); > > it('should send message', async () => { > // await sendMessage(); > }); >
>
> When I run npm run test
, I get the error saying:
>
> plain > FAIL tests/logic/actions/sendMessage.test.ts > ● should send message > > ReferenceError: fetch is not defined > > 43 | const sendMessageInner = async (messages: Message[]) => { > 44 | setMessageListState(messages); > > 45 | const result = await chatSession?.sendMessage(content); > | ^ > 46 | const responseText = result?.response.text(); > 47 | if (responseText) { > 48 | const responseMessage: Message = { > > at makeRequest (node_modules/@google/generative-ai/dist/index.js:246:9) > at generateContent (node_modules/@google/generative-ai/dist/index.js:655:28) > at node_modules/@google/generative-ai/dist/index.js:890:25 > at ChatSession.sendMessage (node_modules/@google/generative-ai/dist/index.js:909:9) > at sendMessageInner (src/logic/actions/sendMessage.ts:45:20) > at src/logic/actions/sendMessage.ts:72:7 > at sendMessage (src/logic/actions/sendMessage.ts:59:3) > at Object.<anonymous> (tests/logic/actions/sendMessage.test.ts:44:3) > >
>
> ...which hints that chatSession.sendMessage
method still uses the real implementation instead of mock.
>
> I'd like to know why this happens and what the solution would be.
>
> Thanks in advance.
>
> ***
>
> # Environment
>
> - Node 20.11.0 (lts/iron)
> - Jest 29.7.0
> - @google/generative-ai
0.5.0 (if relevant)
Third party library mocked with Jest still tries to access internals
I have a function as such:
```typescript export type SendMessageParams = { chatSession?: ChatSession, // ... other params ... };
const sendMessage = async ({ chatSession, // ... other params ... }: SendMessageParams): Promise<void> => { // await chatSession?.sendMessage() // somewhere in implementation };
export default sendMessage; ```
ChatSession is from @google/generative-ai
.
I'd like to mock it in my test file as such:
```typescript let defaultParams: SendMessageParams;
beforeEach(() => { jest.mock('@google/generative-ai', () => ({ ChatSession: { sendMessage: async (content: string) => content, }, })); defaultParams = { chatSession: new ChatSession('', ''), // ... other params ... }; });
afterEach(() => { jest.clearAllMocks(); });
it('should send message', async () => { // await sendMessage(); }); ```
When I run npm run test
, I get the error saying:
```plain FAIL tests/logic/actions/sendMessage.test.ts ● should send message
ReferenceError: fetch is not defined
43 | const sendMessageInner = async (messages: Message[]) => { 44 | setMessageListState(messages); > 45 | const result = await chatSession?.sendMessage(content); | ^ 46 | const responseText = result?.response.text(); 47 | if (responseText) { 48 | const responseMessage: Message = {
at makeRequest (node_modules/@google/generative-ai/dist/index.js:246:9) at generateContent (node_modules/@google/generative-ai/dist/index.js:655:28) at node_modules/@google/generative-ai/dist/index.js:890:25 at ChatSession.sendMessage (node_modules/@google/generative-ai/dist/index.js:909:9) at sendMessageInner (src/logic/actions/sendMessage.ts:45:20) at src/logic/actions/sendMessage.ts:72:7 at sendMessage (src/logic/actions/sendMessage.ts:59:3) at Object.<anonymous> (tests/logic/actions/sendMessage.test.ts:44:3)
```
...which hints that chatSession.sendMessage
method still uses the real implementation instead of mock.
I'd like to know why this happens and what the solution would be.
Thanks in advance.
***
Environment
- Node 20.11.0 (lts/iron)
- Jest 29.7.0
@google/generative-ai
0.5.0 (if relevant)
NPM Unpacked Size for shields.io is now available
If you're a library developer for Javascript or Typescript, a new badge to show unpacked size of your packages is now available.
Badge URL format:
https://img.shields.io/npm/unpacked-size/npmPackageName
Firereact: React hooks, components and utilities for Firebase
React hooks, components and utilities for Firebase - GitHub - erayerdin/firereact: React hooks, components and utilities for Firebase
![GitHub - erayerdin/firereact: React hooks, components and utilities for Firebase](https://programming.dev/pictrs/image/7d5b10ed-21a3-47d4-b954-480e5867fd2b.png?format=webp&thumbnail=256)
cross-posted from: https://programming.dev/post/9577952
> Firereact is hooks, component and utilities library for Firebase and React.
>
> ## Features
>
> - Very lightweight, !unpacked size
> when unpacked, !npm min bundle size when minified, !npm minzip bundle size when minified+gzipped
> - Supports Auth, Firestore, Functions, Providers and Storage.
> - Provides hooks such as useUser
for Auth or useDocument
for Firestore, which can listen to realtime changes as well
> - Provides custom components such as <FirestoreDocument />
or <StorageDownloadLink />
to keep the logic simple and/or avoid unnecessary rerendering
> - Provides Provider
s such as FirebaseSuiteProvider
, FirebaseAuthProvider
or FirestoreProvider
to access Firebase service instances anywhere in the component tree without relying on global variables or prop-drilling
> - Comprehensive documentation
Firereact: React hooks, components and utilities for Firebase
React hooks, components and utilities for Firebase - GitHub - erayerdin/firereact: React hooks, components and utilities for Firebase
![GitHub - erayerdin/firereact: React hooks, components and utilities for Firebase](https://programming.dev/pictrs/image/96f133d5-ac1a-44d9-a962-5689b11c9ee7.png?format=webp&thumbnail=256)
Firereact is hooks, component and utilities library for Firebase and React.
Features
- Very lightweight, !unpacked size when unpacked, !npm min bundle size when minified, !npm minzip bundle size when minified+gzipped
- Supports Auth, Firestore, Functions, Providers and Storage.
- Provides hooks such as
useUser
for Auth oruseDocument
for Firestore, which can listen to realtime changes as well - Provides custom components such as
<FirestoreDocument />
or<StorageDownloadLink />
to keep the logic simple and/or avoid unnecessary rerendering - Provides
Provider
s such asFirebaseSuiteProvider
,FirebaseAuthProvider
orFirestoreProvider
to access Firebase service instances anywhere in the component tree without relying on global variables or prop-drilling - Comprehensive documentation
Thank you, I've used files
to exclude them from the bundle. :)
Vite bundles peer dependencies for library
I've been writing a hook+component library for React and Firebase, the source of which can be seen here.
It reached to a certain stability. My current goal is to reduce the size as much as possible. I've checked documents and stuff and this is the vite.config.ts
that I have:
```typescript import peerDepsExternal from "rollup-plugin-peer-deps-external"; import { defineConfig } from "vite"; import dts from "vite-plugin-dts"; import { peerDependencies } from "./package.json";
export default defineConfig({
build: {
lib: {
entry: "./src/index.ts", // Specifies the entry point for building the library.
name: "firereact", // Sets the name of the generated library.
fileName: (format) => index.${format}.js
, // Generates the output file name based on the format.
formats: ["cjs", "es"], // Specifies the output formats (CommonJS and ES modules).
},
rollupOptions: {
external: [...Object.keys(peerDependencies)], // Defines external dependencies for Rollup bundling.
},
sourcemap: true, // Generates source maps for debugging.
emptyOutDir: true, // Clears the output directory before building.
},
plugins: [dts(), peerDepsExternal()], // Uses the 'vite-plugin-dts' plugin for generating TypeScript declaration files (d.ts).
});
```
build.lib.rollupOptions.external
is to be expected: It gets peer dependencies from package.json
. peerDepsExternal
helps to not bundle the dependencies of peer dependencies.
Still, I've thought the final size is not that reasonable compared to some similar libraries.
That's why I've checked what's being included with npx vite-bundle-visualizer
.
Seems like @firebase
is being included to the final library. I can also confirm it with less dist/index.es.js
and see @firebase
being mangled.
Firebase is a peer dependency so it shouldn't be bundled to the final library (or maybe I misunderstand something cruicial about peerDependencies
).
How do I exclude @firebase
from the library?
***
Troubleshooting
Here are some ways that I've tried to remove @firebase
from the final library:
- Tried to manually add it into
build.lib.rollupOptions.external
invite.config.ts
. - Played with some settings in
tsconfig.json
.
Yep, tried ChatGPT on that but screwed up the project and had to revert back to an older tag for it, but I will try this surely.
Help me understand module system in ES
I've decided to write my first library in Typescript, which is here.
I've got some questions that I don't think is suitable for StackOverflow because it's quite case-specific rather than being generic and I've got a couple of them rather than one.
I'm trying to wrap my head around JS/TS module system for some while. There are some problems with my library:
- If a user imports a hook, they have to do
import { useDocument } from 'firereact/firestore/useDocument'
, but it'd be much better if they could doimport { useDocument } from 'firereact/firestore'
. I've tried many ways but I couldn't export it tofirestore/index.ts
I guess. What am I doing wrong? - I have realized that consumers can also import test modules and
firebase.ts
, which are only used for testing and it is not desirable for them to be imported by the consumers. How can I ignore some specific exports while bundling? They are meant to be used internally.
Thanks in advance. And btw, extra reviews and critics are appreciated since this is going to be my first library.
Using an array and unpacking seems the most genius hacky solution to this problem. Imma go with that I guess.
Using an array and unpacking seems the most genius hacky solution to this problem. Imma go with that I guess.
How can I render a custom component in head
with React Helmet?
I use React Helmet. I wanted to inject social meta tags in some of the pages. In order to DRY, I wanted to define these social meta tags as a separate component, which looks as below:
```typescript type SocialMetaProps = { title: string, description: string, }
const SocialMeta = ({ title, description }: SocialMetaProps) => { return ( <> <meta property="og:title" content={title} /> <meta property="og:description" content={description} /> <meta property="og:url" content={window.location.href} />
<meta property="twitter:title" content={title} /> <meta property="twitter:description" content={description} /> <meta property="twitter:url" content={window.location.href} /> </> ) }
export default SocialMeta ```
...which looks as such when I use it in a page:
typescript <Helmet> <title>{resource.title}</title> <SocialMeta title={resource.title} description={resource.shortDescription} /> </Helmet>
The problem with that is that SocialMeta
component does not render anything. I can confirm it by firing up browser console and doing document.head.getElementsByTagName("meta")
. However, if I do it as below:
```typescript <Helmet> <title>{resource.title}</title>
<meta property="og:title" content={resource.title} /> <meta property="og:description" content={resource.shortDescription} /> <meta property="og:url" content={window.location.href} />
<meta property="twitter:title" content={resource.title} /> <meta property="twitter:description" content={resource.shortDescription} /> <meta property="twitter:url" content={window.location.href} /> </Helmet> ```
...it naturally renders the tags.
My best guess is that Helmet does not unpack <></>
. Is there a way to render a custom component inside Helmet
component?
Thanks in advance.
***
Environment
- Vite
- Typescript
- React ^18.2.0
- Helmet ^6.1.0
- React Router (DOM) ^6.20.1 (if relevant)
Freelancing (?) programmers here: How do you estimate how many scrum points a specific project will require? Is there a template?
I know this is kind of a soft problem and is highly dependent on the context of a project.
For my own projects, I use scrum points to estimate how much effort it will require to reach to a certain point. I measured my throughput and it seems like, with the amount of time left from my daily job, I can complete around 100 points every month.
Recently, this idea is stuck in my head. Every (web/mobile) project requires a certain set of requirements such as:
- Authentication and authorization
- Performance metrics and logging
- Storage
- CRUD for each model etc.
Of course, mostly through Firebase.
I was wondering if there's a way, a website or a platform maybe, to define a list of features/stories and get an estimated total points.
I've even installed a browser extension to filter Medium from Google search results. Their pricing is not reasonable nor localized.
Omniscient - A simple process manager and system information app powered by Tauri, Rust, NextJS and Typescript
Contribute to erayerdin/omniscient development by creating an account on GitHub.
![GitHub - erayerdin/omniscient](https://programming.dev/pictrs/image/8c8eb6fe-57a4-4cde-a912-6bc371f5d192.png?format=webp&thumbnail=256)
This is a process manager and system information app I've written by using Tauri. I've done it to see how Tauri works. PRs are welcome.