cabana: thorough tests for desired bit dragging functionality
parent
8638258eba
commit
9586813cb4
12
package.json
12
package.json
|
@ -4,6 +4,7 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"aphrodite": "^1.2.1",
|
"aphrodite": "^1.2.1",
|
||||||
|
"classnames": "^2.2.5",
|
||||||
"create-react-class": "^15.5.3",
|
"create-react-class": "^15.5.3",
|
||||||
"cuint": "^0.2.2",
|
"cuint": "^0.2.2",
|
||||||
"file-saver": "^1.3.3",
|
"file-saver": "^1.3.3",
|
||||||
|
@ -13,17 +14,17 @@
|
||||||
"int64-buffer": "^0.1.9",
|
"int64-buffer": "^0.1.9",
|
||||||
"moment": "^2.18.1",
|
"moment": "^2.18.1",
|
||||||
"prop-types": "^15.5.10",
|
"prop-types": "^15.5.10",
|
||||||
"react": "^15.5.4",
|
"react": "^15.6.1",
|
||||||
"react-dom": "^15.5.4",
|
"react-dom": "^15.6.1",
|
||||||
"react-infinite": "^0.11.0",
|
"react-infinite": "^0.11.0",
|
||||||
"react-list": "^0.8.6",
|
"react-list": "^0.8.6",
|
||||||
"react-measure": "^1.4.7",
|
"react-measure": "^1.4.7",
|
||||||
|
"react-test-renderer": "^15.6.1",
|
||||||
"react-vega": "^3.0.0",
|
"react-vega": "^3.0.0",
|
||||||
"vega": "git+ssh://git@github.com/commaai/vega.git#HEAD",
|
"vega": "git+ssh://git@github.com/commaai/vega.git#HEAD",
|
||||||
"vega-tooltip": "^0.4.0"
|
"vega-tooltip": "^0.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"worker-loader": "^0.8.0",
|
|
||||||
"autoprefixer": "6.7.2",
|
"autoprefixer": "6.7.2",
|
||||||
"babel-core": "6.22.1",
|
"babel-core": "6.22.1",
|
||||||
"babel-eslint": "7.1.1",
|
"babel-eslint": "7.1.1",
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
"css-loader": "0.26.1",
|
"css-loader": "0.26.1",
|
||||||
"detect-port": "1.1.0",
|
"detect-port": "1.1.0",
|
||||||
"dotenv": "2.0.0",
|
"dotenv": "2.0.0",
|
||||||
|
"enzyme": "^2.9.1",
|
||||||
"eslint": "3.16.1",
|
"eslint": "3.16.1",
|
||||||
"eslint-config-react-app": "^0.6.2",
|
"eslint-config-react-app": "^0.6.2",
|
||||||
"eslint-loader": "1.6.0",
|
"eslint-loader": "1.6.0",
|
||||||
|
@ -61,7 +63,8 @@
|
||||||
"webpack": "1.14.0",
|
"webpack": "1.14.0",
|
||||||
"webpack-dev-server": "1.16.2",
|
"webpack-dev-server": "1.16.2",
|
||||||
"webpack-manifest-plugin": "1.1.0",
|
"webpack-manifest-plugin": "1.1.0",
|
||||||
"whatwg-fetch": "2.0.2"
|
"whatwg-fetch": "2.0.2",
|
||||||
|
"worker-loader": "^0.8.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "python simple-cors-http-server.py & python server.py & node scripts/start.js",
|
"start": "python simple-cors-http-server.py & python server.py & node scripts/start.js",
|
||||||
|
@ -74,6 +77,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
|
"timers": "fake",
|
||||||
"collectCoverageFrom": [
|
"collectCoverageFrom": [
|
||||||
"src/**/*.{js,jsx}"
|
"src/**/*.{js,jsx}"
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,290 @@
|
||||||
|
/*
|
||||||
|
Tests for AddSignals component
|
||||||
|
|
||||||
|
note: 'right' and 'left' in test descriptions
|
||||||
|
refer to the sides of the bit matrix
|
||||||
|
as displayed to the user.
|
||||||
|
*/
|
||||||
|
import AddSignals from '../../components/AddSignals';
|
||||||
|
import React from 'react';
|
||||||
|
import { shallow, mount, render } from 'enzyme';
|
||||||
|
import {StyleSheetTestUtils} from 'aphrodite';
|
||||||
|
|
||||||
|
// Prevents style injection from firing after test finishes
|
||||||
|
// and jsdom is torn down.
|
||||||
|
beforeEach(() => {
|
||||||
|
StyleSheetTestUtils.suppressStyleInjection();
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
StyleSheetTestUtils.clearBufferAndResumeStyleInjection();
|
||||||
|
});
|
||||||
|
|
||||||
|
// signal creation
|
||||||
|
|
||||||
|
function createAddSignals(signals) {
|
||||||
|
if(signals === undefined) {
|
||||||
|
signals = {};
|
||||||
|
}
|
||||||
|
const message = {signals,
|
||||||
|
address: 0,
|
||||||
|
entries: [
|
||||||
|
{relTime: 0,
|
||||||
|
hexData: '0000000000000000'}
|
||||||
|
]};
|
||||||
|
|
||||||
|
const component = shallow(<AddSignals
|
||||||
|
message={message}
|
||||||
|
messageIndex={0}
|
||||||
|
onConfirmedSignalChange={() => {}} />);
|
||||||
|
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
test('double clicking adds a signal', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
|
||||||
|
const firstBit = component.find('.bit').first();
|
||||||
|
|
||||||
|
firstBit.simulate('dblclick');
|
||||||
|
const newSignal = Object.values(component.state('signals'))[0];
|
||||||
|
|
||||||
|
expect(newSignal).toBeDefined();
|
||||||
|
expect(newSignal.size).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dragging right to left across a byte creates a little endian signal', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
const leftBitInByte = component.find('.bit').first();
|
||||||
|
const rightBitInByte = component.find('.bit').at(7);
|
||||||
|
rightBitInByte.simulate('mousedown');
|
||||||
|
leftBitInByte.simulate('mouseup');
|
||||||
|
|
||||||
|
const newSignal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(newSignal).toBeDefined();
|
||||||
|
expect(newSignal.size).toBe(8);
|
||||||
|
expect(newSignal.isLittleEndian).toBe(true);
|
||||||
|
expect(newSignal.startBit).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dragging left to right across a byte creates a big endian signal', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
const leftBitInByte = component.find('.bit').first();
|
||||||
|
const rightBitInByte = component.find('.bit').at(7);
|
||||||
|
leftBitInByte.simulate('mousedown');
|
||||||
|
rightBitInByte.simulate('mouseup');
|
||||||
|
|
||||||
|
const newSignal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(newSignal).toBeDefined();
|
||||||
|
expect(newSignal.size).toBe(8);
|
||||||
|
expect(newSignal.isLittleEndian).toBe(false);
|
||||||
|
expect(newSignal.startBit).toBe(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dragging from the left of byte 0 to right of byte 1 creates a big endian signal spanning both bytes', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
const leftBitInByte = component.find('.bit').first();
|
||||||
|
const rightBitInByte = component.find('.bit').at(15);
|
||||||
|
leftBitInByte.simulate('mousedown');
|
||||||
|
rightBitInByte.simulate('mouseup');
|
||||||
|
|
||||||
|
const newSignal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(newSignal).toBeDefined();
|
||||||
|
expect(newSignal.size).toBe(16);
|
||||||
|
expect(newSignal.isLittleEndian).toBe(false);
|
||||||
|
expect(newSignal.startBit).toBe(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dragging from the right of byte 0 to the left of byte 1 creates a little endian signal spanning both bytes', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
const leftBitInByteOne = component.find('.bit').at(8); // left of byte 1
|
||||||
|
const rightBitInByteZero = component.find('.bit').at(7); // right of byte 0
|
||||||
|
|
||||||
|
rightBitInByteZero.simulate('mousedown');
|
||||||
|
leftBitInByteOne.simulate('mouseup');
|
||||||
|
|
||||||
|
const newSignal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(newSignal).toBeDefined();
|
||||||
|
expect(newSignal.size).toBe(16);
|
||||||
|
expect(newSignal.isLittleEndian).toBe(true);
|
||||||
|
expect(newSignal.startBit).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dragging from the left of byte 1 to the right of byte 0 creates a little endian signal spanning both bytes', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
const leftBitInByteOne = component.find('.bit').at(8);
|
||||||
|
const rightBitInByteZero = component.find('.bit').at(7);
|
||||||
|
|
||||||
|
leftBitInByteOne.simulate('mousedown');
|
||||||
|
rightBitInByteZero.simulate('mouseup');
|
||||||
|
|
||||||
|
const signal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(signal).toBeDefined();
|
||||||
|
expect(signal.size).toBe(16);
|
||||||
|
expect(signal.isLittleEndian).toBe(true);
|
||||||
|
expect(signal.startBit).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dragging from the right of byte 1 to the left of byte 0 creates a big endian signal spanning both bytes', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
const leftBitInByteZero = component.find('.bit').at(0);
|
||||||
|
const rightBitInByteOne = component.find('.bit').at(15);
|
||||||
|
|
||||||
|
rightBitInByteOne.simulate('mousedown');
|
||||||
|
leftBitInByteZero.simulate('mouseup');
|
||||||
|
|
||||||
|
const signal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(signal).toBeDefined();
|
||||||
|
expect(signal.size).toBe(16);
|
||||||
|
expect(signal.isLittleEndian).toBe(false);
|
||||||
|
expect(signal.startBit).toBe(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
// signal mutation
|
||||||
|
|
||||||
|
test('dragging a one-bit big-endian signal to the right should extend it to the right of the byte', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
component.instance().createSignal({startBit: 7, size: 1, isLittleEndian: false});
|
||||||
|
|
||||||
|
const signalBit = component.find('.bit').at(0);
|
||||||
|
signalBit.simulate('mousedown');
|
||||||
|
for(let i = 1; i < 8; i++) {
|
||||||
|
component.find('.bit').at(i).simulate('mouseenter');
|
||||||
|
}
|
||||||
|
const bitAtRightOfFirstByte = component.find('.bit').at(7);
|
||||||
|
bitAtRightOfFirstByte.simulate('mouseup');
|
||||||
|
|
||||||
|
const signal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(signal).toBeDefined();
|
||||||
|
expect(signal.size).toBe(8);
|
||||||
|
expect(signal.isLittleEndian).toBe(false);
|
||||||
|
expect(signal.startBit).toBe(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dragging a one-bit little-endian signal to the right should extend it to the right of the byte', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
component.instance().createSignal({startBit: 7, size: 1, isLittleEndian: true});
|
||||||
|
|
||||||
|
const signalBit = component.find('.bit').at(0);
|
||||||
|
signalBit.simulate('mousedown');
|
||||||
|
for(let i = 1; i < 8; i++) {
|
||||||
|
component.find('.bit').at(i).simulate('mouseenter');
|
||||||
|
}
|
||||||
|
const bitAtRightOfFirstByte = component.find('.bit').at(7);
|
||||||
|
bitAtRightOfFirstByte.simulate('mouseup');
|
||||||
|
|
||||||
|
const signal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(signal).toBeDefined();
|
||||||
|
expect(signal.size).toBe(8);
|
||||||
|
expect(signal.isLittleEndian).toBe(true);
|
||||||
|
expect(signal.startBit).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dragging a one-bit big-endian signal to the left should extend it to the left of the byte', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
component.instance().createSignal({startBit: 0, size: 1, isLittleEndian: false});
|
||||||
|
|
||||||
|
const signalBit = component.find('.bit').at(7);
|
||||||
|
signalBit.simulate('mousedown');
|
||||||
|
for(let i = 6; i > -1; i--) {
|
||||||
|
component.find('.bit').at(i).simulate('mouseenter');
|
||||||
|
}
|
||||||
|
const bitAtRightOfFirstByte = component.find('.bit').at(0);
|
||||||
|
bitAtRightOfFirstByte.simulate('mouseup');
|
||||||
|
|
||||||
|
const signal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(signal).toBeDefined();
|
||||||
|
expect(signal.size).toBe(8);
|
||||||
|
expect(signal.isLittleEndian).toBe(false);
|
||||||
|
expect(signal.startBit).toBe(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('extending a two-bit big-endian signal by its LSB should extend it to the right of the byte', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
component.instance().createSignal({startBit: 7, size: 2, isLittleEndian: false});
|
||||||
|
|
||||||
|
const lsb = component.find('.bit').at(1);
|
||||||
|
lsb.simulate('mousedown');
|
||||||
|
for(let i = 0; i < 8; i++) {
|
||||||
|
component.find('.bit').at(i).simulate('mouseenter');
|
||||||
|
}
|
||||||
|
const bitAtRightOfFirstByte = component.find('.bit').at(7);
|
||||||
|
bitAtRightOfFirstByte.simulate('mouseup');
|
||||||
|
|
||||||
|
const signal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(signal).toBeDefined();
|
||||||
|
expect(signal.size).toBe(8);
|
||||||
|
expect(signal.isLittleEndian).toBe(false);
|
||||||
|
expect(signal.startBit).toBe(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('a two-bit little-endian signal should extend by its LSB to the end of the byte', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
component.instance().createSignal({startBit: 6, size: 2, isLittleEndian: true});
|
||||||
|
|
||||||
|
const lsb = component.find('.bit').at(1);
|
||||||
|
lsb.simulate('mousedown');
|
||||||
|
for(let i = 0; i < 8; i++) {
|
||||||
|
component.find('.bit').at(i).simulate('mouseenter');
|
||||||
|
}
|
||||||
|
const bitAtRightOfFirstByte = component.find('.bit').at(7);
|
||||||
|
bitAtRightOfFirstByte.simulate('mouseup');
|
||||||
|
|
||||||
|
const signal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(signal).toBeDefined();
|
||||||
|
expect(signal.size).toBe(8);
|
||||||
|
expect(signal.isLittleEndian).toBe(true);
|
||||||
|
expect(signal.startBit).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dragging the lsb of a little-endian signal spanning an entire byte should not be allowed to pass the MSB', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
component.instance().createSignal({startBit: 0, size: 8, isLittleEndian: true});
|
||||||
|
|
||||||
|
const lsb = component.find('.bit').at(7);
|
||||||
|
lsb.simulate('mousedown');
|
||||||
|
|
||||||
|
const bitPastMsb = component.find('.bit').at(15);
|
||||||
|
bitPastMsb.simulate('mouseenter');
|
||||||
|
bitPastMsb.simulate('mouseup');
|
||||||
|
|
||||||
|
const signal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(signal).toBeDefined();
|
||||||
|
expect(signal.size).toBe(8);
|
||||||
|
expect(signal.isLittleEndian).toBe(true);
|
||||||
|
expect(signal.startBit).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dragging the lsb of a big-endian signal towards the msb in the same byte should contract the signal', () => {
|
||||||
|
const component = createAddSignals();
|
||||||
|
component.instance().createSignal({startBit: 7, size: 8, isLittleEndian: false});
|
||||||
|
|
||||||
|
const lsb = component.find('.bit').at(7);
|
||||||
|
lsb.simulate('mousedown');
|
||||||
|
for(let i = 6; i > 0; i--) {
|
||||||
|
component.find('.bit').at(i).simulate('mouseenter');
|
||||||
|
}
|
||||||
|
component.find('.bit').at(1).simulate('mouseup');
|
||||||
|
|
||||||
|
const signal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(signal).toBeDefined();
|
||||||
|
expect(signal.size).toBe(2);
|
||||||
|
expect(signal.isLittleEndian).toBe(false);
|
||||||
|
expect(signal.startBit).toBe(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('a big endian signal spanning one byte should switch to little endian preserving its bit coverage', () => {
|
||||||
|
const component = shallowAddSignals();
|
||||||
|
component.instance().createSignal({startBit: 0, size: 8, isLittleEndian: true});
|
||||||
|
|
||||||
|
const lsb = component.find('.bit').at(7);
|
||||||
|
lsb.simulate('mousedown');
|
||||||
|
|
||||||
|
const bitPastMsb = component.find('.bit').at(15);
|
||||||
|
bitPastMsb.simulate('mouseenter');
|
||||||
|
bitPastMsb.simulate('mouseup');
|
||||||
|
|
||||||
|
const signal = Object.values(component.state('signals'))[0];
|
||||||
|
expect(signal).toBeDefined();
|
||||||
|
expect(signal.size).toBe(8);
|
||||||
|
expect(signal.isLittleEndian).toBe(true);
|
||||||
|
expect(signal.startBit).toBe(0);
|
||||||
|
});
|
|
@ -0,0 +1,28 @@
|
||||||
|
import SignalLegend from '../../components/SignalLegend';
|
||||||
|
import React from 'react';
|
||||||
|
import { shallow, mount, render } from 'enzyme';
|
||||||
|
import {StyleSheetTestUtils} from 'aphrodite';
|
||||||
|
|
||||||
|
// Prevents style injection from firing after test finishes
|
||||||
|
// and jsdom is torn down.
|
||||||
|
beforeEach(() => {
|
||||||
|
StyleSheetTestUtils.suppressStyleInjection();
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
StyleSheetTestUtils.clearBufferAndResumeStyleInjection();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('a little endian signal spanning one byte should switch to big endian preserving its bit coverage', () => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
test('a big endian signal spanning two bytes should switch to little endian preserving its bit coverage', () => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
test("a big endian signal spanning one and a half bytes should switch to little endian preserving the first byte's coverage", () => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { StyleSheet, css } from 'aphrodite/no-important';
|
import { StyleSheet } from 'aphrodite/no-important';
|
||||||
|
import css from '../utils/css';
|
||||||
import {hash} from '../utils/string';
|
import {hash} from '../utils/string';
|
||||||
import SignalLegend from './SignalLegend';
|
import SignalLegend from './SignalLegend';
|
||||||
import Signal from '../models/can/signal';
|
import Signal from '../models/can/signal';
|
||||||
|
@ -22,7 +22,6 @@ export default class AddSignals extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
message: PropTypes.object,
|
message: PropTypes.object,
|
||||||
onConfirmedSignalChange: PropTypes.func,
|
onConfirmedSignalChange: PropTypes.func,
|
||||||
onClose: PropTypes.func,
|
|
||||||
messageIndex: PropTypes.number,
|
messageIndex: PropTypes.number,
|
||||||
onSignalPlotChange: PropTypes.func,
|
onSignalPlotChange: PropTypes.func,
|
||||||
plottedSignals: PropTypes.array
|
plottedSignals: PropTypes.array
|
||||||
|
@ -140,14 +139,19 @@ export default class AddSignals extends Component {
|
||||||
|
|
||||||
if(dragStartBit !== null) {
|
if(dragStartBit !== null) {
|
||||||
if(dragSignal !== null) {
|
if(dragSignal !== null) {
|
||||||
if(dragStartBit === dragSignal.startBit) {
|
if(dragStartBit === dragSignal.startBit && dragSignal.size > 1) {
|
||||||
if(!dragSignal.isLittleEndian) {
|
if(!dragSignal.isLittleEndian) {
|
||||||
// should not be able to drag the msb past the lsb
|
// should not be able to drag the msb past the lsb
|
||||||
const startBigEndian = DbcUtils.bigEndianBitIndex(dragStartBit);
|
const startBigEndian = DbcUtils.bigEndianBitIndex(dragStartBit);
|
||||||
const hoveredBigEndian = DbcUtils.bigEndianBitIndex(bitIdx);
|
const hoveredBigEndian = DbcUtils.bigEndianBitIndex(bitIdx);
|
||||||
const lsbPos = (startBigEndian + dragSignal.size - 1);
|
|
||||||
|
|
||||||
if(hoveredBigEndian > lsbPos) {
|
const lsbBigEndian = dragSignal.lsbBitNumber();
|
||||||
|
if(hoveredBigEndian > lsbBigEndian) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// should not be able to drag the lsb past the msb
|
||||||
|
if(bitIdx > dragSignal.msbBitIndex()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,10 +165,33 @@ export default class AddSignals extends Component {
|
||||||
} else {
|
} else {
|
||||||
dragSignal.size -= Math.abs(diff);
|
dragSignal.size -= Math.abs(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
dragSignal.startBit += diff;
|
dragSignal.startBit += diff;
|
||||||
|
|
||||||
signals[dragSignal.name] = dragSignal;
|
signals[dragSignal.name] = dragSignal;
|
||||||
dragStartBit = dragSignal.startBit;
|
dragStartBit = dragSignal.startBit;
|
||||||
|
} else if(dragSignal.size === 1) {
|
||||||
|
// 1-bit signals can be dragged in either direction
|
||||||
|
if(Math.floor(bitIdx / 8) === Math.floor(dragStartBit / 8)) {
|
||||||
|
if(bitIdx > dragStartBit) {
|
||||||
|
if(dragSignal.isLittleEndian) {
|
||||||
|
dragSignal.size = bitIdx - dragSignal.startBit;
|
||||||
|
} else {
|
||||||
|
dragSignal.startBit = bitIdx;
|
||||||
|
dragSignal.size = bitIdx - dragStartBit + 1;
|
||||||
|
dragStartBit = bitIdx;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(dragSignal.isLittleEndian) {
|
||||||
|
dragSignal.startBit = bitIdx;
|
||||||
|
dragSignal.size = dragStartBit - bitIdx + 1;
|
||||||
|
dragStartBit = bitIdx;
|
||||||
|
} else {
|
||||||
|
dragSignal.size = dragStartBit - bitIdx + 1;
|
||||||
|
dragStartBit = bitIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if(dragSignal.isLittleEndian && dragStartBit === dragSignal.msbBitIndex()) {
|
} else if(dragSignal.isLittleEndian && dragStartBit === dragSignal.msbBitIndex()) {
|
||||||
const diff = bitIdx - dragStartBit;
|
const diff = bitIdx - dragStartBit;
|
||||||
if(dragSignal.bitDescription(bitIdx) === null) {
|
if(dragSignal.bitDescription(bitIdx) === null) {
|
||||||
|
@ -216,11 +243,11 @@ export default class AddSignals extends Component {
|
||||||
dragSignal: dragSignal || null})
|
dragSignal: dragSignal || null})
|
||||||
}
|
}
|
||||||
|
|
||||||
createSignalAtBit(bitIdx, size) {
|
createSignal({startBit, size, isLittleEndian}) {
|
||||||
const signal = new Signal({name: this.nextNewSignalName(),
|
const signal = new Signal({name: this.nextNewSignalName(),
|
||||||
startBit: bitIdx,
|
startBit,
|
||||||
size: size,
|
size: size,
|
||||||
isLittleEndian: false});
|
isLittleEndian});
|
||||||
const {signals} = this.state;
|
const {signals} = this.state;
|
||||||
signals[signal.name] = signal;
|
signals[signal.name] = signal;
|
||||||
|
|
||||||
|
@ -236,18 +263,37 @@ export default class AddSignals extends Component {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const isDragAcrossSingleByte = Math.floor(dragEndBit / 8) === Math.floor(dragStartBit / 8);
|
||||||
|
const isDragDirectionUp = !isDragAcrossSingleByte && dragEndBit < dragStartBit;
|
||||||
|
|
||||||
|
let isLittleEndian;
|
||||||
|
if(isDragAcrossSingleByte || !isDragDirectionUp) {
|
||||||
|
isLittleEndian = (dragStartBit % 8 < 4);
|
||||||
|
} else {
|
||||||
|
isLittleEndian = (dragStartBit % 8 >= 4);
|
||||||
|
}
|
||||||
let size, startBit = dragStartBit;
|
let size, startBit = dragStartBit;
|
||||||
|
|
||||||
if(Math.floor(dragEndBit / 8) === Math.floor(dragStartBit / 8)){
|
if(isDragAcrossSingleByte){
|
||||||
size = Math.abs(dragEndBit - dragStartBit) + 1;
|
size = Math.abs(dragEndBit - dragStartBit) + 1;
|
||||||
} else {
|
} else {
|
||||||
if(dragEndBit < dragStartBit) {
|
if(isLittleEndian) {
|
||||||
startBit = dragEndBit;
|
if(dragEndBit > dragStartBit) {
|
||||||
|
startBit = dragStartBit;
|
||||||
|
size = dragEndBit - dragStartBit + 1;
|
||||||
|
} else {
|
||||||
|
startBit = dragEndBit;
|
||||||
|
size = dragStartBit - dragEndBit + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(dragEndBit < dragStartBit) {
|
||||||
|
startBit = dragEndBit;
|
||||||
|
}
|
||||||
|
size = Math.abs(DbcUtils.bigEndianBitIndex(dragEndBit) - DbcUtils.bigEndianBitIndex(dragStartBit)) + 1;
|
||||||
}
|
}
|
||||||
size = Math.abs(DbcUtils.bigEndianBitIndex(dragEndBit) - DbcUtils.bigEndianBitIndex(dragStartBit)) + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.createSignalAtBit(startBit, size);
|
this.createSignal({startBit, size, isLittleEndian});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onBitMouseUp(dragEndBit, signal) {
|
onBitMouseUp(dragEndBit, signal) {
|
||||||
|
@ -285,7 +331,7 @@ export default class AddSignals extends Component {
|
||||||
bitIsContainedInSelection(bitIdx, isLittleEndian = false) {
|
bitIsContainedInSelection(bitIdx, isLittleEndian = false) {
|
||||||
const {dragStartBit, dragCurrentBit} = this.state;
|
const {dragStartBit, dragCurrentBit} = this.state;
|
||||||
|
|
||||||
if(isLittleEndian) {
|
if(isLittleEndian || (dragStartBit % 8 < 4)) {
|
||||||
return dragStartBit !== null && dragCurrentBit !== null
|
return dragStartBit !== null && dragCurrentBit !== null
|
||||||
&& bitIdx >= dragStartBit && bitIdx <= dragCurrentBit;
|
&& bitIdx >= dragStartBit && bitIdx <= dragCurrentBit;
|
||||||
} else {
|
} else {
|
||||||
|
@ -297,13 +343,12 @@ export default class AddSignals extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onBitDoubleClick(bitIdx, signal) {
|
onBitDoubleClick(startBit, signal) {
|
||||||
if(signal === undefined) {
|
if(signal === undefined) {
|
||||||
this.createSignalAtBit(bitIdx, 1);
|
this.createSignal({startBit, size: 1, isLittleEndian: false});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bitMatrix() {
|
bitMatrix() {
|
||||||
const {bits} = this.state;
|
const {bits} = this.state;
|
||||||
const rows = [];
|
const rows = [];
|
||||||
|
@ -327,15 +372,14 @@ export default class AddSignals extends Component {
|
||||||
} else if(this.bitIsContainedInSelection(bitIdx)) {
|
} else if(this.bitIsContainedInSelection(bitIdx)) {
|
||||||
bitStyle = Styles.bitSelectedStyle;
|
bitStyle = Styles.bitSelectedStyle;
|
||||||
}
|
}
|
||||||
const className = css(Styles.bit, bitStyle);
|
const className = css('bit', Styles.bit, bitStyle);
|
||||||
rowBits.push((<td key={j.toString()}
|
rowBits.push((<td key={j.toString()}
|
||||||
className={className}
|
className={className}
|
||||||
onMouseEnter={() => this.onBitHover(bitIdx, signal)}
|
onMouseEnter={() => this.onBitHover(bitIdx, signal)}
|
||||||
onMouseLeave={() => this.onSignalHoverEnd(signal)}
|
onMouseLeave={() => this.onSignalHoverEnd(signal)}
|
||||||
onMouseDown={this.onBitMouseDown.bind(this, bitIdx, signal)}
|
onMouseDown={this.onBitMouseDown.bind(this, bitIdx, signal)}
|
||||||
onMouseUp={this.onBitMouseUp.bind(this, bitIdx, signal)}
|
onMouseUp={this.onBitMouseUp.bind(this, bitIdx, signal)}
|
||||||
onDoubleClick={(() => this.onBitDoubleClick(bitIdx, signal))
|
onDoubleClick={(() => this.onBitDoubleClick(bitIdx, signal))}
|
||||||
}
|
|
||||||
><span>
|
><span>
|
||||||
{this.bitValue(i, j)}
|
{this.bitValue(i, j)}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import { StyleSheet, css } from 'aphrodite/no-important';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import {css} from 'aphrodite/no-important';
|
||||||
|
|
||||||
import Modal from './Modal';
|
import Modal from './Modal';
|
||||||
import DBC from '../models/can/dbc';
|
import DBC from '../models/can/dbc';
|
||||||
|
|
|
@ -185,7 +185,6 @@ export default class RouteSeeker extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {seekedBarStyle, markerStyle, tooltipStyle} = this.state;
|
const {seekedBarStyle, markerStyle, tooltipStyle} = this.state;
|
||||||
return (<div className={this.props.className}>
|
return (<div className={this.props.className}>
|
||||||
|
|
|
@ -93,7 +93,7 @@ export default class SignalLegendEntry extends Component {
|
||||||
|
|
||||||
let titleCol = <td>{title}</td>;
|
let titleCol = <td>{title}</td>;
|
||||||
|
|
||||||
return <tr>{titleCol}<td>{valueCol}</td></tr>;
|
return <tr key={field}>{titleCol}<td>{valueCol}</td></tr>;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateField(field, value) {
|
updateField(field, value) {
|
||||||
|
|
|
@ -66,14 +66,23 @@ export default class Signal {
|
||||||
}
|
}
|
||||||
|
|
||||||
lsbBitIndex() {
|
lsbBitIndex() {
|
||||||
|
// Returns LSB bit index in matrix order (see AddSignals.js)
|
||||||
|
|
||||||
if(this.isLittleEndian) {
|
if(this.isLittleEndian) {
|
||||||
return this.startBit;
|
return this.startBit;
|
||||||
} else {
|
} else {
|
||||||
const lsbBitNumber = DbcUtils.bigEndianBitIndex(this.startBit) + this.size - 1;
|
const lsbBitNumber = this.lsbBitNumber();
|
||||||
|
|
||||||
return DbcUtils.matrixBitNumber(lsbBitNumber);
|
return DbcUtils.matrixBitNumber(lsbBitNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lsbBitNumber() {
|
||||||
|
// Returns LSB bit number in big endian ordering
|
||||||
|
|
||||||
|
return DbcUtils.bigEndianBitIndex(this.startBit) + this.size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
msbBitIndex() {
|
msbBitIndex() {
|
||||||
if(this.isLittleEndian) {
|
if(this.isLittleEndian) {
|
||||||
return this.startBit + this.size - 1;
|
return this.startBit + this.size - 1;
|
||||||
|
|
Loading…
Reference in New Issue