Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ide/vscode/src/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const Version = "9.0.18";
export const Version = "9.0.20";
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ const component_test: Record<string, ComponentCheck<Internal.BehaviorPack.Block>
'minecraft:geometry': (name, component, context, diagnoser) => {
try {
if (
!context.isPermutation &&
!context.components.includes('minecraft:material_instances') &&
FormatVersion.isGreaterOrEqualThan(context.source.format_version as FormatVersion, [1, 21, 80])
)
Expand Down Expand Up @@ -114,6 +115,7 @@ const component_test: Record<string, ComponentCheck<Internal.BehaviorPack.Block>
'minecraft:material_instances': (name, component, context, diagnoser) => {
try {
if (
!context.isPermutation &&
!context.components.includes('minecraft:geometry') &&
FormatVersion.isGreaterOrEqualThan(context.source.format_version as FormatVersion, [1, 21, 80])
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function diagnose_block_document(diagnoser: DocumentDiagnosticsBuilder):
//check components
block['minecraft:block']?.permutations?.forEach((p) => {
context.components.push(...getUsedComponents(p));
behaviorpack_diagnose_block_components(p, context, diagnoser);
behaviorpack_diagnose_block_components(p, { ...context, isPermutation: true }, diagnoser);
});

if (block['minecraft:block']['events']) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export interface Context<T> {
source: Readonly<T>;
/** The components used by the source collected from multiple sources */
components: string[];
/** Whether the current components being checked belong to a permutation (not the top-level block) */
isPermutation?: boolean;
Comment thread
DaanV2 marked this conversation as resolved.
}

/**Checks if components dependencies are present, a component might need others to be present
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { Internal } from 'bc-minecraft-bedrock-project';
import { TestDiagnoser } from '../../../diagnoser';
import { behaviorpack_diagnose_block_components } from '../../../../src/diagnostics/behavior-pack/block/components/diagnose';
import { Context } from '../../../../src/utility/components';

const FORMAT_VERSION_1_21_80 = '1.21.80';
const FORMAT_VERSION_1_20_0 = '1.20.0';

function makeBlock(formatVersion: string): Internal.BehaviorPack.Block {
return {
format_version: formatVersion,
'minecraft:block': {
description: { identifier: 'test:block' },
components: {},
},
};
}

function makeContext(
block: Internal.BehaviorPack.Block,
components: string[],
isPermutation?: boolean,
): Context<Internal.BehaviorPack.Block> {
return { source: block, components, isPermutation };
}

describe('BehaviorPack', () => {
describe('Block', () => {
describe('minecraft:geometry / minecraft:material_instances pairing', () => {
it('errors when geometry is at top-level without material_instances (>= 1.21.80)', () => {
const diagnoser = TestDiagnoser.create();
const block = makeBlock(FORMAT_VERSION_1_21_80);
const context = makeContext(block, ['minecraft:geometry']);

behaviorpack_diagnose_block_components(
{ components: { 'minecraft:geometry': 'geometry.example' } },
context,
diagnoser,
);
Comment on lines +31 to +39
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestDiagnoser.create() returns a TestDiagnoser which implements ManagedDiagnosticsBuilder but not DocumentDiagnosticsBuilder. The function behaviorpack_diagnose_block_components expects a DocumentDiagnosticsBuilder (which requires a document property). While this works at runtime because document is never accessed in this code path, it's a type mismatch that ts-jest may flag as a compilation error. Consider using TestDiagnoser.createDocument(undefined, doc) to create a TestDocumentDiagnoser (as done in block-properties.test.ts), or cast the diagnoser with as any.

Copilot uses AI. Check for mistakes.

expect(diagnoser.hasCode('behaviorpack.block.components.material_instances_x_geometry')).toBe(true);
});

it('errors when material_instances is at top-level without geometry (>= 1.21.80)', () => {
const diagnoser = TestDiagnoser.create();
const block = makeBlock(FORMAT_VERSION_1_21_80);
const context = makeContext(block, ['minecraft:material_instances']);

behaviorpack_diagnose_block_components(
{ components: { 'minecraft:material_instances': { '*': { texture: 'test' } } } },
context,
diagnoser,
);

expect(diagnoser.hasCode('behaviorpack.block.components.material_instances_x_geometry')).toBe(true);
});

it('does not error when geometry is in a permutation without material_instances (>= 1.21.80)', () => {
const diagnoser = TestDiagnoser.create();
const block = makeBlock(FORMAT_VERSION_1_21_80);
const context = makeContext(block, ['minecraft:geometry'], true);

behaviorpack_diagnose_block_components(
{ components: { 'minecraft:geometry': 'geometry.example' } },
context,
diagnoser,
);

expect(diagnoser.hasCode('behaviorpack.block.components.material_instances_x_geometry')).toBe(false);
});

it('does not error when material_instances is in a permutation without geometry (>= 1.21.80)', () => {
const diagnoser = TestDiagnoser.create();
const block = makeBlock(FORMAT_VERSION_1_21_80);
const context = makeContext(block, ['minecraft:material_instances'], true);

behaviorpack_diagnose_block_components(
{ components: { 'minecraft:material_instances': { '*': { texture: 'test' } } } },
context,
diagnoser,
);

expect(diagnoser.hasCode('behaviorpack.block.components.material_instances_x_geometry')).toBe(false);
});

it('does not error when both geometry and material_instances are present at top-level (>= 1.21.80)', () => {
const diagnoser = TestDiagnoser.create();
const block = makeBlock(FORMAT_VERSION_1_21_80);
const context = makeContext(block, ['minecraft:geometry', 'minecraft:material_instances']);

behaviorpack_diagnose_block_components(
{
components: {
'minecraft:geometry': 'geometry.example',
'minecraft:material_instances': { '*': { texture: 'test' } },
},
},
context,
diagnoser,
);

expect(diagnoser.hasCode('behaviorpack.block.components.material_instances_x_geometry')).toBe(false);
});

it('does not error when geometry is used without material_instances in format versions < 1.21.80', () => {
const diagnoser = TestDiagnoser.create();
const block = makeBlock(FORMAT_VERSION_1_20_0);
const context = makeContext(block, ['minecraft:geometry']);

behaviorpack_diagnose_block_components(
{ components: { 'minecraft:geometry': 'geometry.example' } },
context,
diagnoser,
);

expect(diagnoser.hasCode('behaviorpack.block.components.material_instances_x_geometry')).toBe(false);
});
});
});
});
Loading