cabana: switching endianness of a signal located in a single byte doesn't change bit coverage

main
Andy Haden 2017-06-27 15:08:15 -07:00
parent ae3f243078
commit bcf01a584d
4 changed files with 81 additions and 18 deletions

View File

@ -288,3 +288,20 @@ test('a big endian signal spanning one byte should switch to little endian prese
expect(signal.isLittleEndian).toBe(true);
expect(signal.startBit).toBe(0);
});
test('dragging the msb of a 2-bit little endian signal to a lower byte should not change the signal', () => {
const component = createAddSignals();
component.instance().createSignal({startBit: 14, size: 2, isLittleEndian: true});
const msb = component.find('.bit').at(8);
msb.simulate('mousedown');
const bitOutOfBounds = component.find('.bit').at(0);
bitOutOfBounds.simulate('mouseenter');
bitOutOfBounds.simulate('mouseup');
const signal = Object.values(component.state('signals'))[0];
expect(signal).toBeDefined();
expect(signal.size).toBe(2);
expect(signal.isLittleEndian).toBe(true);
expect(signal.startBit).toBe(14);
});

View File

@ -14,31 +14,34 @@ afterEach(() => {
});
function createSignalLegendEntry(props) {
let signal = props.signal, onSignalChange = props.onSignalChange;
let signal = props.signal,
onSignalChange = props.onSignalChange,
onTentativeSignalChange = props.onTentativeSignalChange;
if(signal === undefined) {
signal = new Signal({name: 'NEW_SIGNAL'});
}
if(onSignalChange === undefined) {
onSignalChange = () => {};
}
if(onTentativeSignalChange === undefined) {
onTentativeSignalChange = () => {};
}
return shallow(<SignalLegendEntry
highlightedStyle={null}
signal={signal}
onSignalChange={onSignalChange}
onTentativeSignalChange={onTentativeSignalChange}
/>);
}
test('a little endian signal spanning one byte should adjust its startBit switching to big endian, preserving its bit coverage', () => {
const mockOnSignalChange = jest.fn();
const signal = new Signal({name: 'signal',
startBit: 0,
size: 8,
isLittleEndian: true});
const props = {onSignalChange: mockOnSignalChange,
signal};
const component = createSignalLegendEntry(props);
const component = createSignalLegendEntry({signal});
const endiannessFieldSpec = SignalLegendEntry.fieldSpecForName('isLittleEndian');
component.instance().updateField(endiannessFieldSpec, false);
@ -49,15 +52,11 @@ test('a little endian signal spanning one byte should adjust its startBit switch
});
test('a big endian signal spanning two bytes should should adjust its startBit switching to little endian, preserving its bit coverage', () => {
const mockOnSignalChange = jest.fn();
const signal = new Signal({name: 'signal',
startBit: 7,
size: 8,
isLittleEndian: false});
const props = {onSignalChange: mockOnSignalChange,
signal};
const component = createSignalLegendEntry(props);
const component = createSignalLegendEntry({signal});
const endiannessFieldSpec = SignalLegendEntry.fieldSpecForName('isLittleEndian');
component.instance().updateField(endiannessFieldSpec, true);
@ -68,15 +67,12 @@ test('a big endian signal spanning two bytes should should adjust its startBit s
});
test("a big endian signal spanning one and a half bytes should adjust its startBit switching to little endian, preserving the first byte's coverage", () => {
const mockOnSignalChange = jest.fn();
const signal = new Signal({name: 'signal',
startBit: 7,
size: 12,
isLittleEndian: false});
const props = {onSignalChange: mockOnSignalChange,
signal};
const component = createSignalLegendEntry(props);
const component = createSignalLegendEntry({signal});
const endiannessFieldSpec = SignalLegendEntry.fieldSpecForName('isLittleEndian');
component.instance().updateField(endiannessFieldSpec, true);
@ -85,3 +81,33 @@ test("a big endian signal spanning one and a half bytes should adjust its startB
expect(signalEdited.startBit).toBe(0);
expect(signalEdited.size).toBe(12);
});
test('a little endian signal spanning 3 bits on one byte should adjust its startBit switching to big endian, preserving its bit coverage', () => {
const signal = new Signal({name: 'signal',
startBit: 13,
size: 3,
isLittleEndian: true});
const component = createSignalLegendEntry({signal});
const endiannessFieldSpec = SignalLegendEntry.fieldSpecForName('isLittleEndian');
component.instance().updateField(endiannessFieldSpec, false);
const signalEdited = component.state('signalEdited');
expect(signalEdited.isLittleEndian).toBe(false);
expect(signalEdited.startBit).toBe(15);
expect(signalEdited.size).toBe(3);
});
test('a big endian signal spanning 3 bytes on one byte should adjust its startBit switching to little endian, preserving its bit coverage', () => {
const signal = new Signal({name: 'signal',
startBit: 15,
size: 3,
isLittleEndian: false});
const component = createSignalLegendEntry({signal});
const endiannessFieldSpec = SignalLegendEntry.fieldSpecForName('isLittleEndian');
component.instance().updateField(endiannessFieldSpec, true);
const signalEdited = component.state('signalEdited');
expect(signalEdited.isLittleEndian).toBe(true);
expect(signalEdited.startBit).toBe(13);
expect(signalEdited.size).toBe(3);
});

View File

@ -194,6 +194,10 @@ export default class AddSignals extends Component {
}
}
} else if(dragSignal.isLittleEndian && dragStartBit === dragSignal.msbBitIndex()) {
if(bitIdx < dragSignal.startBit) {
// should not be able to drag the MSB past the LSB
return;
}
const diff = bitIdx - dragStartBit;
if(dragSignal.bitDescription(bitIdx) === null) {
dragSignal.size += Math.abs(diff);

View File

@ -60,12 +60,27 @@ export default class SignalLegendEntry extends Component {
transform: (isLittleEndian, signal) => {
if(signal.isLittleEndian !== isLittleEndian) {
const {startBit} = signal;
if(isLittleEndian) {
// big endian -> little endian
signal.startBit = DbcUtils.matrixBitNumber(startBit);
const startByte = Math.floor(signal.startBit / 8),
endByte = Math.floor((signal.startBit - signal.size + 1) / 8);
if(startByte === endByte) {
signal.startBit = signal.startBit - signal.size + 1;
} else {
signal.startBit = DbcUtils.matrixBitNumber(startBit);
}
} else {
// little endian -> big endian
signal.startBit = DbcUtils.bigEndianBitIndex(startBit);
const startByte = Math.floor(signal.startBit / 8),
endByte = Math.floor((signal.startBit + signal.size - 1) / 8);
if(startByte === endByte) {
signal.startBit = signal.startBit + signal.size - 1;
} else {
signal.startBit = DbcUtils.bigEndianBitIndex(startBit);
}
}
signal.isLittleEndian = isLittleEndian;
}
@ -125,6 +140,7 @@ export default class SignalLegendEntry extends Component {
};
this.toggleEditing = this.toggleEditing.bind(this);
this.updateField = this.updateField.bind(this);
}
componentWillReceiveProps(nextProps) {