1// Copyright 2021 The Cirq Developers 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import {expect} from 'chai'; 16import {Symbol3D, SymbolInformation} from './types'; 17import {BoxGate3DSymbol, Control3DSymbol, X3DSymbol} from './meshes'; 18 19describe('Symbol3D', () => { 20 describe('with valid one qubit SymbolInformation objects', () => { 21 const symbols: SymbolInformation[] = [ 22 { 23 wire_symbols: ['X'], 24 location_info: [{row: 0, col: 0}], 25 color_info: ['black'], 26 moment: 1, 27 }, 28 { 29 wire_symbols: ['@'], 30 location_info: [{row: 1, col: 2}], 31 color_info: ['black'], 32 moment: 3, 33 }, 34 { 35 wire_symbols: ['Y'], 36 location_info: [{row: 3, col: 2}], 37 color_info: ['purple'], 38 moment: 7, 39 }, 40 ]; 41 42 it('handles the X gate special case', () => { 43 const symbolObj = new Symbol3D(symbols[0]); 44 const xSymbol = symbolObj.children[0]; 45 expect(xSymbol instanceof X3DSymbol).to.equal(true); 46 }); 47 48 it('handles the control symbol special case', () => { 49 const symbolObj = new Symbol3D(symbols[1]); 50 const ctrlSymbol = symbolObj.children[0]; 51 expect(ctrlSymbol instanceof Control3DSymbol).to.equal(true); 52 }); 53 54 it('handles an arbitrary symbol with a box', () => { 55 const symbolObj = new Symbol3D(symbols[2]); 56 const boxSymbol = symbolObj.children[0]; 57 expect(boxSymbol instanceof BoxGate3DSymbol).to.equal(true); 58 }); 59 60 it('builds every symbol in the correct location on the scene', () => { 61 const expectedRows = [0, 1, 3]; 62 const expectedCols = [0, 2, 2]; 63 const expectedMoments = [1, 3, 7]; 64 symbols.forEach((value, index) => { 65 const symbol = new Symbol3D(value).children[0]; 66 expect(symbol.position.x).to.equal(expectedRows[index]); 67 expect(symbol.position.y).to.equal(expectedMoments[index]); 68 expect(symbol.position.z).to.equal(expectedCols[index]); 69 }); 70 }); 71 }); 72 73 describe('with valid multi-qubit SymbolInformation objects', () => { 74 const symbols: SymbolInformation[] = [ 75 { 76 wire_symbols: ['@', 'X'], 77 location_info: [ 78 {row: 0, col: 0}, 79 {row: 0, col: 1}, 80 ], 81 color_info: ['black', 'black'], 82 moment: 1, 83 }, 84 { 85 wire_symbols: ['×', '×'], 86 location_info: [ 87 {row: 0, col: 0}, 88 {row: 0, col: 1}, 89 ], 90 color_info: ['black', 'black'], 91 moment: 3, 92 }, 93 { 94 wire_symbols: ['iSWAP', 'iSWAP'], 95 location_info: [ 96 {row: 3, col: 2}, 97 {row: 3, col: 3}, 98 ], 99 color_info: ['#d3d3d3', '#d3d3d3'], 100 moment: 7, 101 }, 102 { 103 wire_symbols: ['@', '@', 'X'], 104 location_info: [ 105 {row: 0, col: 0}, 106 {row: 0, col: 1}, 107 {row: 0, col: 2}, 108 ], 109 color_info: ['black', 'black', 'black'], 110 moment: 1, 111 }, 112 ]; 113 114 it('handles a control symbol and an X gate (CNOT)', () => { 115 const symbolObj = new Symbol3D(symbols[0]); 116 117 const ctrlSymbol = symbolObj.children.find( 118 child => child.constructor.name === 'Control3DSymbol' 119 ); 120 expect(ctrlSymbol).to.not.equal(undefined); 121 expect(ctrlSymbol?.position.x).to.equal(0); 122 expect(ctrlSymbol?.position.z).to.equal(0); 123 expect(ctrlSymbol?.position.y).to.equal(1); 124 125 const xSymbol = symbolObj.children.find( 126 child => child.constructor.name === 'X3DSymbol' 127 ); 128 expect(xSymbol).to.not.equal(undefined); 129 expect(xSymbol?.position.x).to.equal(0); 130 expect(xSymbol?.position.z).to.equal(1); 131 expect(xSymbol?.position.y).to.equal(1); 132 133 const connectionLine = symbolObj.children.find( 134 child => child.constructor.name === 'ConnectionLine' 135 ); 136 137 expect(connectionLine).to.not.equal(undefined); 138 }); 139 140 it('handles a two Swap3DSymbol objects correctly (SWAP)', () => { 141 const symbolObj = new Symbol3D(symbols[1]); 142 143 const boxSymbols = symbolObj.children.filter( 144 child => child.constructor.name === 'Swap3DSymbol' 145 ); 146 expect(boxSymbols.length).to.equal(2); 147 148 const expectedRows = [0, 0]; 149 const expectedCols = [0, 1]; 150 boxSymbols.forEach((value, index) => { 151 expect(value.position.x).to.equal(expectedRows[index]); 152 expect(value.position.z).to.equal(expectedCols[index]); 153 expect(value.position.y).to.equal(3); 154 }); 155 156 const connectionLine = symbolObj.children.find( 157 child => child.constructor.name === 'ConnectionLine' 158 ); 159 expect(connectionLine).to.not.equal(undefined); 160 }); 161 162 it('handles a two BoxGate3DSymbol objects correctly (iSWAP)', () => { 163 const symbolObj = new Symbol3D(symbols[2]); 164 165 const boxSymbols = symbolObj.children.filter( 166 child => child.constructor.name === 'BoxGate3DSymbol' 167 ); 168 expect(boxSymbols.length).to.equal(2); 169 170 const expectedRows = [3, 3]; 171 const expectedCols = [2, 3]; 172 boxSymbols.forEach((value, index) => { 173 expect(value.position.x).to.equal(expectedRows[index]); 174 expect(value.position.z).to.equal(expectedCols[index]); 175 expect(value.position.y).to.equal(7); 176 }); 177 178 const connectionLine = symbolObj.children.find( 179 child => child.constructor.name === 'ConnectionLine' 180 ); 181 expect(connectionLine).to.not.equal(undefined); 182 }); 183 184 it('handles two control symbols and an X gate correctly (Toffoli)', () => { 185 const symbolObj = new Symbol3D(symbols[3]); 186 187 const boxSymbols = symbolObj.children.filter( 188 child => child.constructor.name === 'Control3DSymbol' 189 ); 190 expect(boxSymbols.length).to.equal(2); 191 192 const xSymbol = symbolObj.children.find( 193 child => child.constructor.name === 'X3DSymbol' 194 ); 195 expect(xSymbol).to.not.equal(undefined); 196 197 const expectedRows = [0, 0, 0]; 198 const expectedCols = [0, 1, 2]; 199 boxSymbols.forEach((value, index) => { 200 expect(value.position.x).to.equal(expectedRows[index]); 201 expect(value.position.z).to.equal(expectedCols[index]); 202 expect(value.position.y).to.equal(1); 203 }); 204 205 const connectionLines = symbolObj.children.filter( 206 child => child.constructor.name === 'ConnectionLine' 207 ); 208 expect(connectionLines.length).to.equal(2); 209 }); 210 }); 211}); 212