Conversation
There was a problem hiding this comment.
I like what the tests are testing. That's exactly what I meant and wanted to see! 🙇🏼
I think the tests would be better and more robust to changes if we reduced the frequency of mockedObject and defined objects more fully. What are other people's thoughts?
| }); | ||
|
|
||
| it("should return [] if item is a usage", async () => { | ||
| const item = { usages: undefined } as unknown as ModelDetailsTreeViewItem; |
There was a problem hiding this comment.
Can we avoid using as unknown as X? Instead define a proper Usage object.
|
|
||
| describe("getChildren", () => { | ||
| const externalApiUsages: ExternalApiUsage[] = [ | ||
| mockedObject<ExternalApiUsage>({ supported: true }), |
There was a problem hiding this comment.
I see that the desire here is to avoid the pain of providing full objects, but mockedObject is going to potentially cause some issues here that will be hard to debug for future developers. I think you've already hit this, as evidenced by needing to pass usages: undefined in some cases.
In ModelDetailsDataProvider we use isExternalApiUsage to determine if the object we have is an ExternalApiUsage or a Usage. Unfortunately this check won't work correctly when given an object created using mockedObject, or at least you have to know exactly what you're doing and pass the right field values to make isExternalApiUsage behave correctly. While it is possible to have everything work correctly like this, it's quite error prone.
While it's is great for things like CodeQLCliServer, I would recommend not using mockedObject for types like ExternalApiUsage and Usage. How much effort would it be to not do this?
| methodParameters: "test", | ||
| }, | ||
| ]; | ||
| const dbItem = mockedObject<DatabaseItem>({ |
There was a problem hiding this comment.
We define the exact same dbItem in each describe block. Could we move the definition one level higher, like where we make mockCliServer?
| }); | ||
|
|
||
| it("should reveal the correct item in the tree view", async () => { | ||
| const externalApiUsages = mockedObject<ExternalApiUsage[]>([ |
There was a problem hiding this comment.
Again as commented on the other file, I suggest avoiding using mockedObject for the ExternalApiUsage type. We already define a full ExternalApiUsage object earlier in this file, so could we reuse that? Or perhaps add a factory method for making ExternalApiUsage objects (see the test/factories directory)?
charisk
left a comment
There was a problem hiding this comment.
LGTM! Just some comments for potential improvements.
| }); | ||
|
|
||
| it("should show all externalApiUsages if hideModeledApis is false and item is undefined", async () => { | ||
| const hideModeledApis: boolean = false; |
There was a problem hiding this comment.
(Minor) you shouldn't need to define the type
| const hideModeledApis: boolean = false; | |
| const hideModeledApis = false; |
Same on L132 and a few places in model-details-panel.test.ts - worth doing a search for const hideModeledApis: boolean = to find all occurrences.
| beforeEach(() => { | ||
| mockTreeView = { | ||
| reveal: jest.fn(), | ||
| } as unknown as TreeView<unknown>; |
There was a problem hiding this comment.
This is similar to as any as X so we should ideally avoid it. Is there a way to get around it easily, or is creating mock TreeView<>T> items too painful? I'm happy to take it on as tech debt too.
There was a problem hiding this comment.
The problem lies in the reveal: jest.fn(). Without it we could remove the as unknown. With it we would have to mock the vs code reveal method better. I'm not sure if that is easily possible? We only check if reveal was called, not what it does. Therefore I leaned towards leaving it as is. However, can we introduce other errors by using as unknown here apart from the reveal method?
There was a problem hiding this comment.
Lets leave it as is. I imagine creating the mock properly isn't trivial.
There was a problem hiding this comment.
Thanks for talking this through. I think mockedObject could be a good solution for this case. I've opened #2768 for this where I've tried to explain my reasoning, so let me know what you think.
| expect(dataProvider.getChildren(externalApiUsage)).toEqual([usage]); | ||
| }); | ||
|
|
||
| it("should show all externalApiUsages if hideModeledApis is false and item is undefined", async () => { |
There was a problem hiding this comment.
(Minor) The item is undefined bit confused me a little bit but I realised what it meant once I got to know the code a bit better. We don't have to change it, but do you think the following description is accurate/better:
| it("should show all externalApiUsages if hideModeledApis is false and item is undefined", async () => { | |
| it("should show all externalApiUsages if hideModeledApis is false and looking at the root", async () => { |
There was a problem hiding this comment.
sounds good, will rename!
Adds tests for
Checklist
ready-for-doc-reviewlabel there.