Best Python code snippet using slash
test_populate.py
Source:test_populate.py
1#!/usr/bin/env python32# -*- coding: utf-8 -*-3# Copyright (c) 2018 Bhojpur Consulting Private Limited, India. All rights reserved.4#5# Permission is hereby granted, free of charge, to any person obtaining a copy6# of this software and associated documentation files (the "Software"), to deal7# in the Software without restriction, including without limitation the rights8# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell9# copies of the Software, and to permit persons to whom the Software is10# furnished to do so, subject to the following conditions:11#12# The above copyright notice and this permission notice shall be included in13# all copies or substantial portions of the Software.14#15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN21# THE SOFTWARE.22"""23 Test of the Tables service with the populate_metadata.py24 and populate_roi.py scripts.25"""26from ode.testlib import ITest27import string28import csv29import gzip30import os.path31import re32import shutil33import sys34from ode.api import RoiOptions35from ode.grid import ImageColumn36from ode.grid import RoiColumn37from ode.grid import StringColumn38from ode.model import OriginalFileI39from ode.model import FileAnnotationI, MapAnnotationI, PlateAnnotationLinkI40from ode.model import RoiAnnotationLinkI41from ode.model import RoiI, PointI, ProjectI, ScreenI42from ode.rtypes import rdouble, rlist, rstring, unwrap43from ode.sys import ParametersI44from ode.util.populate_metadata import (45 get_config,46 ParsingContext,47 BulkToMapAnnotationContext,48 DeleteMapAnnotationContext,49)50from ode.util.populate_roi import AbstractMeasurementCtx51from ode.util.populate_roi import AbstractPlateAnalysisCtx52from ode.util.populate_roi import MeasurementParsingResult53from ode.util.populate_roi import PlateAnalysisCtxFactory54from ode.constants.namespaces import NSBULKANNOTATIONS55from ode.constants.namespaces import NSMEASUREMENT56from ode.util.temp_files import create_path57from ode.util.metadata_mapannotations import MapAnnotationPrimaryKeyException58from ode.util.metadata_utils import NSBULKANNOTATIONSCONFIG59from pytest import mark60from pytest import raises61MAPR_NS_GENE = 'bhojpur.net/mapr/gene'62pythonminver = mark.skipif(sys.version_info < (2, 7),63 reason="requires python2.7")64def coord2offset(coord):65 """66 Convert a coordinate of the form AB12 into 0-based row-column indices67 TODO: This should go into a utils file somewhere68 """69 ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'70 m = re.match('([A-Z]+)([0-9]+)$', coord.upper())71 assert m72 ra, ca = m.groups()73 r = 074 for a in ra:75 r = r * 26 + ALPHA.find(a) + 176 c = int(ca)77 return r - 1, c - 178class Fixture(object):79 def init(self, test):80 self.test = test81 def setName(self, obj, name):82 q = self.test.client.sf.getQueryService()83 up = self.test.client.sf.getUpdateService()84 obj = q.get(obj.__class__.__name__, obj.id.val)85 obj.setName(rstring(name))86 return up.saveAndReturnObject(obj)87 def createCsv(88 self,89 colNames="Well,Well Type,Concentration",90 rowData=("A1,Control,0", "A2,Treatment,10")91 ):92 csvFileName = create_path("test", ".csv")93 csvFile = open(csvFileName, 'w')94 try:95 csvFile.write(colNames)96 csvFile.write("\n")97 csvFile.write("\n".join(rowData))98 finally:99 csvFile.close()100 return str(csvFileName)101 def createProject(self, name, datasets=("D001", "D002"),102 images=("A1", "A2")):103 prj = ProjectI()104 prj.setName(rstring(name))105 for x in datasets:106 ds = self.createDataset(names=images)107 ds = self.setName(ds, x)108 prj.linkDataset(ds.proxy())109 return self.test.client.sf.getUpdateService().saveAndReturnObject(prj)110 def createDataset(self, names=("A1", "A2")):111 ds = self.test.make_dataset()112 imgs = self.test.import_fake_file(113 images_count=len(names))114 for i, name in enumerate(names):115 # Name must match exactly. No ".fake"116 img = imgs[i]117 img = self.setName(img, name)118 self.test.link(ds, img)119 return ds.proxy()120 def createScreen(self, rowCount, colCount):121 plate1 = self.test.import_plates(plate_rows=rowCount,122 plate_cols=colCount)[0]123 plate2 = self.test.import_plates(plate_rows=rowCount,124 plate_cols=colCount)[0]125 plate1 = self.setName(plate1, "P001")126 plate2 = self.setName(plate2, "P002")127 screen = ScreenI()128 screen.name = rstring("Screen")129 screen.linkPlate(plate1.proxy())130 screen.linkPlate(plate2.proxy())131 return self.test.client.sf.getUpdateService().\132 saveAndReturnObject(screen)133 def createPlate(self, rowCount, colCount):134 plates = self.test.import_plates(plate_rows=rowCount,135 plate_cols=colCount)136 return plates[0]137 def get_csv(self):138 return self.csv139 def get_cfg(self):140 return os.path.join(141 os.path.dirname(__file__), 'bulk_to_map_annotation_context.yml')142 def get_namespaces(self):143 return [NSBULKANNOTATIONS]144 def assert_rows(self, rows):145 assert rows == self.rowCount * self.colCount146 def assert_child_annotations(self, oas):147 for ma, wid, wr, wc in oas:148 assert isinstance(ma, MapAnnotationI)149 assert unwrap(ma.getNs()) == NSBULKANNOTATIONS150 mv = ma.getMapValueAsMap()151 assert mv['Well'] == str(wid)152 assert coord2offset(mv['Well Name']) == (wr, wc)153 if (wr, wc) == (0, 0):154 assert mv['Well Type'] == 'Control'155 assert mv['Concentration'] == '0'156 else:157 assert mv['Well Type'] == 'Treatment'158 assert mv['Concentration'] == '10'159 def get_all_map_annotations(self):160 qs = self.test.client.sf.getQueryService()161 q = "FROM MapAnnotation WHERE ns in (:nss)"162 p = ParametersI()163 p.map['nss'] = rlist(rstring(ns) for ns in self.get_namespaces())164 r = qs.findAllByQuery(q, p)165 return r166class Screen2Plates(Fixture):167 def __init__(self):168 self.count = 6169 self.annCount = 4170 self.rowCount = 1171 self.colCount = 2172 self.csv = self.createCsv(173 colNames="Plate,Well,Well Type,Concentration",174 rowData=("P001,A1,Control,0", "P001,A2,Treatment,10",175 "P002,A1,Control,0", "P002,A2,Treatment,10"))176 self.screen = None177 def assert_rows(self, rows):178 """179 Double the number of rows due to 2 plates.180 """181 assert rows == 2 * self.rowCount * self.colCount182 def get_target(self):183 if not self.screen:184 self.screen = self.createScreen(self.rowCount, self.colCount)185 return self.screen186 def get_annotations(self):187 query = """select s from Screen s188 left outer join fetch s.annotationLinks links189 left outer join fetch links.child190 where s.id=%s""" % self.screen.id.val191 qs = self.test.client.sf.getQueryService()192 screen = qs.findByQuery(query, None)193 anns = screen.linkedAnnotationList()194 return anns195 def get_child_annotations(self):196 query = """197 SELECT wal.child,wal.parent.id,wal.parent.row,wal.parent.column198 FROM WellAnnotationLink wal join wal.parent well199 join well.plate p join p.screenLinks l join l.parent s200 WHERE s.id=%d""" % self.screen.id.val201 qs = self.test.client.sf.getQueryService()202 was = unwrap(qs.projection(query, None))203 return was204class Plate2Wells(Fixture):205 def __init__(self):206 self.count = 4207 self.annCount = 2208 self.rowCount = 1209 self.colCount = 2210 self.csv = self.createCsv()211 self.plate = None212 def get_target(self):213 if not self.plate:214 self.plate = self.createPlate(self.rowCount, self.colCount)215 return self.plate216 def get_annotations(self):217 query = """select p from Plate p218 left outer join fetch p.annotationLinks links219 left outer join fetch links.child220 where p.id=%s""" % self.plate.id.val221 qs = self.test.client.sf.getQueryService()222 plate = qs.findByQuery(query, None)223 anns = plate.linkedAnnotationList()224 return anns225 def get_child_annotations(self, ns=None):226 query = """227 SELECT wal.child,wal.parent.id,wal.parent.row,wal.parent.column228 FROM WellAnnotationLink wal229 WHERE wal.parent.plate.id=%d""" % self.plate.id.val230 if ns is not None:231 query += (" AND wal.child.ns='%s'" % ns)232 qs = self.test.client.sf.getQueryService()233 was = unwrap(qs.projection(query, None))234 return was235class Plate2WellsNs(Plate2Wells):236 # For this test use explicit files instead of generating them as an237 # additional safeguard against changes in the test code238 def __init__(self):239 self.count = 8240 self.annCount = 8 * 2 # Two namespaces241 self.rowCount = 2242 self.colCount = 4243 d = os.path.dirname(__file__)244 self.csv = os.path.join(d, 'bulk_to_map_annotation_context_ns.csv')245 self.plate = None246 def get_cfg(self):247 return os.path.join(os.path.dirname(__file__),248 'bulk_to_map_annotation_context_ns.yml')249 def get_namespaces(self):250 return [NSBULKANNOTATIONS, MAPR_NS_GENE]251 def assert_row_values(self, rowvalues):252 # First column is the WellID253 assert rowvalues[0][1:] == (254 "FBgn0004644", "hh", "hedgehog;bar-3;CG4637", "a1")255 assert rowvalues[1][1:] == (256 "FBgn0003656", "sws", "swiss cheese;olfE;CG2212", "a2")257 assert rowvalues[2][1:] == (258 "FBgn0011236", "ken", "ken and barbie;CG5575", "a3")259 assert rowvalues[3][1:] == (260 "FBgn0086378", "", "Alg-2", "a4")261 assert rowvalues[4][1:] == (262 "", "hh",263 "DHH;IHH;SHH;Desert hedgehog;Indian hedgehog;Sonic hedgehog", "b1")264 assert rowvalues[5][1:] == (265 "", "sws",266 "PNPLA6;patatin like phospholipase domain containing 6", "b2")267 assert rowvalues[6][1:] == (268 "", "ken", "BCL6;B-cell lymphoma 6 protein", "b3")269 assert rowvalues[7][1:] == (270 "", "", "Alg-2", "b4")271 def assert_child_annotations(self, oas):272 wellrcs = [coord2offset(c) for c in (273 'a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4')]274 nss = [NSBULKANNOTATIONS, MAPR_NS_GENE]275 wellrc_ns = [(wrc, ns) for wrc in wellrcs for ns in nss]276 check = dict((k, None) for k in wellrc_ns)277 annids = []278 for ma, wid, wr, wc in oas:279 assert isinstance(ma, MapAnnotationI)280 annids.append(unwrap(ma.getId()))281 ns = unwrap(ma.getNs())282 wrc = (wr, wc)283 # Well names/ids aren't included in this test, because this also284 # test that annotations are combined by primary key285 assert (wrc, ns) in check, 'Unexpected well/namespace'286 assert check[(wrc, ns)] is None, 'Duplicate annotation'287 # Use getMapValue to check ordering and duplicates288 check[(wrc, ns)] = [(p.name, p.value) for p in ma.getMapValue()]289 # Row a290 assert check[(wellrcs[0], nss[0])] == [291 ('Gene', 'hh'),292 ('FlyBase URL', 'http://flybase.org/reports/FBgn0004644.html'),293 ]294 assert check[(wellrcs[0], nss[1])] == [295 ('Gene', 'hh'),296 ('Gene name', 'hedgehog'),297 ('Gene name', 'bar-3'),298 ('Gene name', 'CG4637'),299 ]300 assert check[(wellrcs[1], nss[0])] == [301 ('Gene', 'sws'),302 ('FlyBase URL', 'http://flybase.org/reports/FBgn0003656.html'),303 ]304 assert check[(wellrcs[1], nss[1])] == [305 ('Gene', 'sws'),306 ('Gene name', 'swiss cheese'),307 ('Gene name', 'olfE'),308 ('Gene name', 'CG2212'),309 ]310 assert check[(wellrcs[2], nss[0])] == [311 ('Gene', 'ken'),312 ('FlyBase URL', 'http://flybase.org/reports/FBgn0011236.html'),313 ]314 assert check[(wellrcs[2], nss[1])] == [315 ('Gene', 'ken'),316 ('Gene name', 'ken and barbie'),317 ('Gene name', 'CG5575'),318 ]319 assert check[(wellrcs[3], nss[0])] == [320 ('Gene', ''),321 ('FlyBase URL', 'http://flybase.org/reports/FBgn0086378.html'),322 ]323 assert check[(wellrcs[3], nss[1])] == [324 ('Gene', ''),325 ('Gene name', 'Alg-2'),326 ]327 # Row b328 assert check[(wellrcs[4], nss[0])] == [329 ('Gene', 'hh'),330 ]331 assert check[(wellrcs[4], nss[1])] == [332 ('Gene', 'hh'),333 ('Gene name', 'DHH'),334 ('Gene name', 'IHH'),335 ('Gene name', 'SHH'),336 ('Gene name', 'Desert hedgehog'),337 ('Gene name', 'Indian hedgehog'),338 ('Gene name', 'Sonic hedgehog'),339 ]340 assert check[(wellrcs[5], nss[0])] == [341 ('Gene', 'sws'),342 ]343 assert check[(wellrcs[5], nss[1])] == [344 ('Gene', 'sws'),345 ('Gene name', 'PNPLA6'),346 ('Gene name', 'patatin like phospholipase domain containing 6'),347 ]348 assert check[(wellrcs[6], nss[0])] == [349 ('Gene', 'ken'),350 ]351 assert check[(wellrcs[6], nss[1])] == [352 ('Gene', 'ken'),353 ('Gene name', 'BCL6'),354 ('Gene name', 'B-cell lymphoma 6 protein'),355 ]356 assert check[(wellrcs[7], nss[0])] == [357 ('Gene', ''),358 ]359 assert check[(wellrcs[7], nss[1])] == [360 ('Gene', ''),361 ('Gene name', 'Alg-2'),362 ]363 assert len(annids) == 16364 assert len(set(annids)) == 16365class Plate2WellsNs2(Plate2WellsNs):366 # For this test use explicit files instead of generating them as an367 # additional safeguard against changes in the test code368 def __init__(self):369 super(Plate2WellsNs2, self).__init__()370 def get_cfg(self):371 return os.path.join(os.path.dirname(__file__),372 'bulk_to_map_annotation_context_ns2.yml')373 def assert_child_annotations(self, oas, onlyns=None):374 """375 Pass onlyns to check that only annotations in that namespace exist376 """377 wellrcs = [coord2offset(c) for c in (378 'a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4')]379 nss = [NSBULKANNOTATIONS, MAPR_NS_GENE]380 if onlyns:381 nss = [onlyns]382 wellrc_ns = [(wrc, ns) for wrc in wellrcs for ns in nss]383 check = dict((k, None) for k in wellrc_ns)384 annids = []385 for ma, wid, wr, wc in oas:386 assert isinstance(ma, MapAnnotationI)387 annids.append(unwrap(ma.getId()))388 ns = unwrap(ma.getNs())389 wrc = (wr, wc)390 # Well names/ids aren't included in this test, because this also391 # test that annotations are combined by primary key392 assert (wrc, ns) in check, 'Unexpected well/namespace'393 assert check[(wrc, ns)] is None, 'Duplicate annotation'394 # Use getMapValue to check ordering and duplicates395 check[(wrc, ns)] = [(p.name, p.value) for p in ma.getMapValue()]396 if onlyns == NSBULKANNOTATIONS:397 self._assert_nsbulkann(check, wellrcs)398 assert len(annids) == 8399 assert len(set(annids)) == 8400 if onlyns == MAPR_NS_GENE:401 self._assert_nsgeneann(check, wellrcs)402 assert len(annids) == 8403 assert len(set(annids)) == 4404 if not onlyns:405 self._assert_nsgeneann(check, wellrcs)406 assert len(annids) == 16407 assert len(set(annids)) == 12408 def _assert_nsbulkann(self, check, wellrcs):409 # Row a410 assert check[(wellrcs[0], NSBULKANNOTATIONS)] == [411 ('Gene', 'hh'),412 ('FlyBase URL', 'http://flybase.org/reports/FBgn0004644.html'),413 ]414 assert check[(wellrcs[1], NSBULKANNOTATIONS)] == [415 ('Gene', 'sws'),416 ('FlyBase URL', 'http://flybase.org/reports/FBgn0003656.html'),417 ]418 assert check[(wellrcs[2], NSBULKANNOTATIONS)] == [419 ('Gene', 'ken'),420 ('FlyBase URL', 'http://flybase.org/reports/FBgn0011236.html'),421 ]422 assert check[(wellrcs[3], NSBULKANNOTATIONS)] == [423 ('Gene', ''),424 ('FlyBase URL', 'http://flybase.org/reports/FBgn0086378.html'),425 ]426 # Row b427 assert check[(wellrcs[4], NSBULKANNOTATIONS)] == [428 ('Gene', 'hh'),429 ]430 assert check[(wellrcs[5], NSBULKANNOTATIONS)] == [431 ('Gene', 'sws'),432 ]433 assert check[(wellrcs[6], NSBULKANNOTATIONS)] == [434 ('Gene', 'ken'),435 ]436 assert check[(wellrcs[7], NSBULKANNOTATIONS)] == [437 ('Gene', ''),438 ]439 def _assert_nsgeneann(self, check, wellrcs):440 # Row a441 assert check[(wellrcs[0], MAPR_NS_GENE)] == [442 ('Gene', 'hh'),443 ('Gene name', 'hedgehog'),444 ('Gene name', 'bar-3'),445 ('Gene name', 'CG4637'),446 ('Gene name', 'DHH'),447 ('Gene name', 'IHH'),448 ('Gene name', 'SHH'),449 ('Gene name', 'Desert hedgehog'),450 ('Gene name', 'Indian hedgehog'),451 ('Gene name', 'Sonic hedgehog'),452 ]453 assert check[(wellrcs[1], MAPR_NS_GENE)] == [454 ('Gene', 'sws'),455 ('Gene name', 'swiss cheese'),456 ('Gene name', 'olfE'),457 ('Gene name', 'CG2212'),458 ('Gene name', 'PNPLA6'),459 ('Gene name', 'patatin like phospholipase domain containing 6'),460 ]461 assert check[(wellrcs[2], MAPR_NS_GENE)] == [462 ('Gene', 'ken'),463 ('Gene name', 'ken and barbie'),464 ('Gene name', 'CG5575'),465 ('Gene name', 'BCL6'),466 ('Gene name', 'B-cell lymphoma 6 protein'),467 ]468 assert check[(wellrcs[3], MAPR_NS_GENE)] == [469 ('Gene', ''),470 ('Gene name', 'Alg-2'),471 ]472 # Row b473 assert check[(wellrcs[4], MAPR_NS_GENE)] == check[474 (wellrcs[0], MAPR_NS_GENE)]475 assert check[(wellrcs[5], MAPR_NS_GENE)] == check[476 (wellrcs[1], MAPR_NS_GENE)]477 assert check[(wellrcs[6], MAPR_NS_GENE)] == check[478 (wellrcs[2], MAPR_NS_GENE)]479 assert check[(wellrcs[7], MAPR_NS_GENE)] == [480 ('Gene', ''),481 ('Gene name', 'Alg-2'),482 ]483class Plate2WellsNs2UnavailableHeader(Plate2WellsNs2):484 # For this test use explicit files instead of generating them as an485 # additional safeguard against changes in the test code486 def __init__(self):487 self.count = 4488 self.annCount = 4*2489 self.rowCount = 2490 self.colCount = 2491 self.csv = self.createCsv(492 colNames="Well,Gene,Gene Names",493 rowData=("a1,gene-a1,a1-name", "a2,gene-a2,a2-name",494 "b1,gene-a1,a1-name", "b2,gene-a2,a2-name")495 )496 self.plate = None497 def get_cfg(self):498 return os.path.join(os.path.dirname(__file__),499 'bulk_to_map_annotation_context_ns2_empty.yml')500 def assert_child_annotations(self, oas):501 wellrcs = [coord2offset(c) for c in (502 'a1', 'a2', 'b1', 'b2')]503 nss = [NSBULKANNOTATIONS, MAPR_NS_GENE]504 wellrc_ns = [(wrc, ns) for wrc in wellrcs for ns in nss]505 check = dict((k, None) for k in wellrc_ns)506 annids = []507 for ma, wid, wr, wc in oas:508 assert isinstance(ma, MapAnnotationI)509 annids.append(unwrap(ma.getId()))510 ns = unwrap(ma.getNs())511 wrc = (wr, wc)512 # Well names/ids aren't included in this test, because this also513 # test that annotations are combined by primary key514 assert (wrc, ns) in check, 'Unexpected well/namespace'515 assert check[(wrc, ns)] is None, 'Duplicate annotation'516 # Use getMapValue to check ordering and duplicates517 check[(wrc, ns)] = [(p.name, p.value) for p in ma.getMapValue()]518 # Row a519 assert check[(wellrcs[0], nss[0])] == [520 ('Gene', 'gene-a1'),521 ('Gene name', 'a1-name'),522 ('Gene ID', '')523 ]524 assert check[(wellrcs[1], nss[0])] == [525 ('Gene', 'gene-a2'),526 ('Gene name', 'a2-name'),527 ('Gene ID', '')528 ]529 assert check[(wellrcs[0], nss[1])] == [530 ('Gene', 'gene-a1'),531 ('Gene name', 'a1-name'),532 ('Gene ID', '')533 ]534class Plate2WellsNs2Fail(Plate2WellsNs2):535 # For this test use explicit files instead of generating them as an536 # additional safeguard against changes in the test code537 def __init__(self):538 self.count = 4539 self.annCount = 2540 self.rowCount = 1541 self.colCount = 2542 self.csv = self.createCsv(543 colNames="Well,Gene,Gene Names",544 rowData=("a1,,ABC", "A2,,ABC")545 )546 self.plate = None547 def get_cfg(self):548 return os.path.join(os.path.dirname(__file__),549 'bulk_to_map_annotation_context_ns2_fail.yml')550 def get_namespaces(self):551 return 'bhojpur.net/mapr/gene_fail'552class Dataset2Images(Fixture):553 def __init__(self):554 self.count = 4555 self.annCount = 2556 self.csv = self.createCsv(557 colNames="Image Name,Type,Concentration",558 )559 self.dataset = None560 self.images = None561 self.names = ("A1", "A2")562 def assert_rows(self, rows):563 # Hard-coded in createCsv's arguments564 assert rows == 2565 def get_target(self):566 if not self.dataset:567 self.dataset = self.createDataset(self.names)568 self.images = self.get_dataset_images()569 return self.dataset570 def get_dataset_images(self):571 if not self.dataset:572 return []573 query = """select i from Image i574 left outer join fetch i.datasetLinks links575 left outer join fetch links.parent d576 where d.id=%s""" % self.dataset.id.val577 qs = self.test.client.sf.getQueryService()578 return qs.findAllByQuery(query, None)579 def get_annotations(self):580 query = """select d from Dataset d581 left outer join fetch d.annotationLinks links582 left outer join fetch links.child583 where d.id=%s""" % self.dataset.id.val584 qs = self.test.client.sf.getQueryService()585 ds = qs.findByQuery(query, None)586 anns = ds.linkedAnnotationList()587 return anns588 def get_child_annotations(self):589 if not self.images:590 return []591 params = ParametersI()592 params.addIds([x.id for x in self.images])593 query = """ select a, i.id, 'NA', 'NA'594 from Image i595 left outer join i.annotationLinks links596 left outer join links.child as a597 where i.id in (:ids) and a <> null"""598 qs = self.test.client.sf.getQueryService()599 return unwrap(qs.projection(query, params))600 def assert_child_annotations(self, oas):601 for ma, iid, na1, na2 in oas:602 assert isinstance(ma, MapAnnotationI)603 assert unwrap(ma.getNs()) == NSBULKANNOTATIONS604 mv = ma.getMapValueAsMap()605 img = mv['Image Name']606 con = mv['Concentration']607 typ = mv['Type']608 assert img[0] in ("A", "a")609 which = long(img[1:])610 if which % 2 == 1:611 assert con == '0'612 assert typ == 'Control'613 elif which % 2 == 0:614 assert con == '10'615 assert typ == 'Treatment'616class Dataset2Images1Missing(Dataset2Images):617 def __init__(self):618 super(Dataset2Images1Missing, self).__init__()619 self.annCount = 1620 def get_target(self):621 """622 Temporarily alter self.names so that the super623 invocation creates fewer images than are expected.624 """625 old = self.names626 try:627 self.names = old[0:-1] # Skip last628 return super(Dataset2Images1Missing, self).get_target()629 finally:630 self.names = old631class Dataset101Images(Dataset2Images):632 def __init__(self):633 self.count = 4634 self.annCount = 102635 self.names = []636 rowData = []637 for x in range(0, 101, 2):638 name = "A%s" % (x+1)639 self.names.append(name)640 rowData.append("%s,Control,0" % name)641 name = "A%s" % (x+2)642 self.names.append(name)643 rowData.append("A%s,Treatment,10" % (x+2))644 self.csv = self.createCsv(645 colNames="Image Name,Type,Concentration",646 rowData=rowData,647 )648 self.dataset = None649 self.images = None650 def assert_rows(self, rows):651 assert rows == 102652class GZIP(Dataset2Images):653 def createCsv(self, *args, **kwargs):654 csvFileName = super(GZIP, self).createCsv(*args, **kwargs)655 gzipFileName = "%s.gz" % csvFileName656 # failing on python 2.6657 # the following workaround can be reverted once py26 is dropped658 # with open(csvFileName, 'rb') as f_in:659 # with gzip.open(gzipFileName, 'wb') as f_out:660 # shutil.copyfileobj(f_in, f_out)661 f_in = open(csvFileName, 'rb')662 try:663 try:664 try:665 f_out = gzip.open(gzipFileName, 'wb')666 except:667 f_out = gzip(gzipFileName, 'wb')668 shutil.copyfileobj(f_in, f_out)669 finally:670 f_out.close()671 finally:672 f_in.close()673 return gzipFileName674class Project2Datasets(Fixture):675 def __init__(self):676 self.count = 5677 self.annCount = 4678 self.csv = self.createCsv(679 colNames="Dataset Name,Image Name,Type,Concentration",680 rowData=("D001,A1,Control,0", "D001,A2,Treatment,10",681 "D002,A1,Control,0", "D002,A2,Treatment,10"))682 self.project = None683 def assert_rows(self, rows):684 # Hard-coded in createCsv's arguments685 assert rows == 4686 def get_target(self):687 if not self.project:688 self.project = self.createProject("P123")689 self.images = self.get_project_images()690 return self.project691 def get_project_images(self):692 if not self.project:693 return []694 query = """select i from Image i695 left outer join fetch i.datasetLinks dil696 left outer join fetch dil.parent d697 left outer join fetch d.projectLinks pdl698 left outer join fetch pdl.parent p699 where p.id=%s""" % self.project.id.val700 qs = self.test.client.sf.getQueryService()701 return qs.findAllByQuery(query, None)702 def get_annotations(self):703 query = """select p from Project p704 left outer join fetch p.annotationLinks links705 left outer join fetch links.child706 where p.id=%s""" % self.project.id.val707 qs = self.test.client.sf.getQueryService()708 ds = qs.findByQuery(query, None)709 anns = ds.linkedAnnotationList()710 return anns711 def get_child_annotations(self):712 if not self.images:713 return []714 params = ParametersI()715 params.addIds([x.id for x in self.images])716 query = """ select a, i.id, 'NA', 'NA'717 from Image i718 left outer join i.annotationLinks links719 left outer join links.child as a720 where i.id in (:ids) and a <> null"""721 qs = self.test.client.sf.getQueryService()722 return unwrap(qs.projection(query, params))723 def assert_child_annotations(self, oas):724 for ma, iid, na1, na2 in oas:725 assert isinstance(ma, MapAnnotationI)726 assert unwrap(ma.getNs()) == NSBULKANNOTATIONS727 mv = ma.getMapValueAsMap()728 ds = mv['Dataset Name']729 img = mv['Image Name']730 con = mv['Concentration']731 typ = mv['Type']732 if ds == 'D001' or ds == 'D002':733 if img == "A1":734 assert con == '0'735 assert typ == 'Control'736 elif img == "A2":737 assert con == '10'738 assert typ == 'Treatment'739 else:740 raise Exception("Unknown img: %s" % img)741 else:742 raise Exception("Unknown dataset: %s" % ds)743@pythonminver744class TestPopulateMetadataConfigLoad(ITest):745 def get_cfg_filepath(self):746 return os.path.join(os.path.dirname(__file__),747 'bulk_to_map_annotation_context.yml')748 def _assert_configs(self, default_cfg, column_cfgs, advanced_cfgs):749 assert default_cfg == {"include": True}750 assert column_cfgs is None751 assert advanced_cfgs == {}752 def test_get_config_local(self):753 default_cfg, column_cfgs, advanced_cfgs = get_config(754 None, cfg=self.get_cfg_filepath())755 self._assert_configs(default_cfg, column_cfgs, advanced_cfgs)756 def test_get_config_remote(self):757 ofile = self.client.upload(self.get_cfg_filepath()).proxy()758 cfgid = unwrap(ofile.getId())759 default_cfg, column_cfgs, advanced_cfgs = get_config(760 self.client.getSession(), cfgid=cfgid)761 self._assert_configs(default_cfg, column_cfgs, advanced_cfgs)762@pythonminver763class TestPopulateMetadataHelper(ITest):764 def _test_parsing_context(self, fixture, batch_size):765 """766 Create a small csv file, use populate_metadata.py to parse and767 attach to Plate. Then query to check table has expected content.768 """769 target = fixture.get_target()770 # Deleting anns so that we can re-use the same user771 self.delete(fixture.get_annotations())772 child_anns = fixture.get_child_annotations()773 child_anns = [x[0] for x in child_anns]774 self.delete(child_anns)775 csv = fixture.get_csv()776 ctx = ParsingContext(self.client, target, file=csv)777 ctx.parse()778 if batch_size is None:779 ctx.write_to_ode()780 else:781 ctx.write_to_ode(batch_size=batch_size, loops=10, ms=250)782 # Get file annotations783 anns = fixture.get_annotations()784 # Only expect a single annotation which is a 'bulk annotation'785 assert len(anns) == 1786 tableFileAnn = anns[0]787 assert unwrap(tableFileAnn.getNs()) == NSBULKANNOTATIONS788 fileid = tableFileAnn.file.id.val789 # Open table to check contents790 r = self.client.sf.sharedResources()791 t = r.openTable(OriginalFileI(fileid), None)792 return t793 def _assert_parsing_context_values(self, t, fixture):794 cols = t.getHeaders()795 rows = t.getNumberOfRows()796 fixture.assert_rows(rows)797 for hit in range(rows):798 rowValues = [col.values[0] for col in t.read(range(len(cols)),799 hit, hit+1).columns]800 assert len(rowValues) == fixture.count801 # Unsure where the lower-casing is happening802 if "A1" in rowValues or "a1" in rowValues:803 assert "Control" in rowValues804 elif "A2" in rowValues or "a2" in rowValues:805 assert "Treatment" in rowValues806 def _test_bulk_to_map_annotation_context(self, fixture, batch_size):807 # self._testPopulateMetadataPlate()808 assert len(fixture.get_all_map_annotations()) == 0809 assert len(fixture.get_child_annotations()) == 0810 cfg = fixture.get_cfg()811 target = fixture.get_target()812 anns = fixture.get_annotations()813 fileid = anns[0].file.id.val814 ctx = BulkToMapAnnotationContext(815 self.client, target, fileid=fileid, cfg=cfg)816 ctx.parse()817 assert len(fixture.get_child_annotations()) == 0818 if batch_size is None:819 ctx.write_to_ode()820 else:821 ctx.write_to_ode(batch_size=batch_size)822 oas = fixture.get_child_annotations()823 assert len(oas) == fixture.annCount824 fixture.assert_child_annotations(oas)825 def _test_delete_map_annotation_context(self, fixture, batch_size):826 # self._test_bulk_to_map_annotation_context()827 assert len(fixture.get_child_annotations()) == fixture.annCount828 cfg = fixture.get_cfg()829 target = fixture.get_target()830 ctx = DeleteMapAnnotationContext(self.client, target, cfg=cfg)831 ctx.parse()832 assert len(fixture.get_child_annotations()) == fixture.annCount833 if batch_size is None:834 ctx.write_to_ode()835 else:836 ctx.write_to_ode(batch_size=batch_size)837 assert len(fixture.get_child_annotations()) == 0838 assert len(fixture.get_all_map_annotations()) == 0839@pythonminver840class TestPopulateMetadataHelperPerMethod(TestPopulateMetadataHelper):841 # Some tests in this file check the counts of annotations in a fixed842 # namespace, and therefore require a new client for each test method843 def setup_class(cls):844 pass845 def teardown_class(cls):846 pass847 def setup_method(self, method):848 super(TestPopulateMetadataHelperPerMethod, self).setup_class()849 def teardown_method(self, method):850 super(TestPopulateMetadataHelperPerMethod, self).teardown_class()851@pythonminver852class TestPopulateMetadata(TestPopulateMetadataHelper):853 METADATA_FIXTURES = (854 Screen2Plates(),855 Plate2Wells(),856 Dataset2Images(),857 Dataset2Images1Missing(),858 Dataset101Images(),859 Project2Datasets(),860 GZIP(),861 )862 METADATA_IDS = [x.__class__.__name__ for x in METADATA_FIXTURES]863 METADATA_NS_FIXTURES = (864 Plate2WellsNs(),865 Plate2WellsNs2(),866 )867 METADATA_NS_IDS = [x.__class__.__name__ for x in METADATA_NS_FIXTURES]868 @mark.parametrize("fixture", METADATA_FIXTURES, ids=METADATA_IDS)869 @mark.parametrize("batch_size", (None, 1, 10))870 def testPopulateMetadata(self, fixture, batch_size):871 """872 We should really test each of the parsing contexts in separate tests873 but in practice each one uses data created by the others, so for874 now just run them all together875 """876 fixture.init(self)877 t = self._test_parsing_context(fixture, batch_size)878 self._assert_parsing_context_values(t, fixture)879 self._test_bulk_to_map_annotation_context(fixture, batch_size)880 self._test_delete_map_annotation_context(fixture, batch_size)881 @mark.parametrize("fixture", METADATA_NS_FIXTURES, ids=METADATA_NS_IDS)882 def testPopulateMetadataNsAnns(self, fixture):883 """884 Test complicated annotations (multiple ns/groups) on a single Bhojpur ODE885 data type, as opposed to testPopulateMetadata which tests simple886 annotations on multiple Bhojpur ODE data types887 """888 fixture.init(self)889 t = self._test_parsing_context(fixture, 2)890 cols = t.getHeaders()891 rows = t.getNumberOfRows()892 fixture.assert_rows(rows)893 data = [c.values for c in t.read(range(len(cols)), 0, rows).columns]894 rowValues = zip(*data)895 assert len(rowValues) == fixture.count896 fixture.assert_row_values(rowValues)897 self._test_bulk_to_map_annotation_context(fixture, 2)898 self._test_delete_map_annotation_context(fixture, 2)899 def testPopulateMetadataNsAnnsUnavailableHeader(self):900 """901 Similar to testPopulateMetadataNsAnns but use two plates and check902 MapAnnotations aren't duplicated903 """904 fixture_empty = Plate2WellsNs2UnavailableHeader()905 fixture_empty.init(self)906 self._test_parsing_context(fixture_empty, 2)907 self._test_bulk_to_map_annotation_context(fixture_empty, 2)908 def testPopulateMetadataNsAnnsFail(self):909 """910 Similar to testPopulateMetadataNsAnns but use two plates and check911 MapAnnotations aren't duplicated912 """913 fixture_fail = Plate2WellsNs2Fail()914 fixture_fail.init(self)915 self._test_parsing_context(fixture_fail, 2)916 with raises(MapAnnotationPrimaryKeyException):917 self._test_bulk_to_map_annotation_context(fixture_fail, 2)918@pythonminver919class TestPopulateMetadataDedup(TestPopulateMetadataHelperPerMethod):920 # Hard-code the number of expected map-annotations in these tests921 # since the code in this file is complicated enough without trying922 # to parameterise this923 def _test_bulk_to_map_annotation_dedup(self, fixture1, fixture2, ns):924 options = {}925 if ns:926 options['ns'] = ns927 ann_count = fixture1.annCount928 assert fixture2.annCount == ann_count929 assert len(fixture1.get_child_annotations()) == ann_count930 assert len(fixture2.get_child_annotations()) == 0931 cfg = fixture2.get_cfg()932 target = fixture2.get_target()933 anns = fixture2.get_annotations()934 fileid = anns[0].file.id.val935 ctx = BulkToMapAnnotationContext(936 self.client, target, fileid=fileid, cfg=cfg, options=options)937 ctx.parse()938 assert len(fixture1.get_child_annotations()) == ann_count939 assert len(fixture2.get_child_annotations()) == 0940 ctx.write_to_ode()941 oas1 = fixture1.get_child_annotations()942 oas2 = fixture2.get_child_annotations()943 assert len(oas1) == ann_count944 if ns == NSBULKANNOTATIONS:945 assert len(oas2) == 8946 fixture1.assert_child_annotations(oas1)947 fixture2.assert_child_annotations(oas2, ns)948 if ns == MAPR_NS_GENE:949 assert len(oas2) == 8950 fixture1.assert_child_annotations(oas1)951 fixture2.assert_child_annotations(oas2, ns)952 if ns is None:953 assert len(oas2) == ann_count954 fixture1.assert_child_annotations(oas1)955 fixture2.assert_child_annotations(oas2)956 # The gene mapannotations should be common957 ids1 = set(unwrap(o[0].getId()) for o in oas1)958 ids2 = set(unwrap(o[0].getId()) for o in oas2)959 common = ids1.intersection(ids2)960 if ns == NSBULKANNOTATIONS:961 assert len(common) == 0962 else:963 assert len(common) == 4964 def _test_delete_map_annotation_context_dedup(965 self, fixture1, fixture2, ns):966 # Sanity checks in case the test code or fixtures are modified967 assert fixture1.annCount == 16968 assert fixture2.annCount == 16969 options = {}970 if ns:971 options['ns'] = ns972 assert len(fixture1.get_child_annotations()) == 16973 assert len(fixture1.get_child_annotations(NSBULKANNOTATIONS)) == 8974 assert len(fixture1.get_child_annotations(MAPR_NS_GENE)) == 8975 assert len(fixture2.get_child_annotations()) == 16976 assert len(fixture2.get_child_annotations(NSBULKANNOTATIONS)) == 8977 assert len(fixture2.get_child_annotations(MAPR_NS_GENE)) == 8978 assert len(fixture2.get_all_map_annotations()) == 20979 ctx = DeleteMapAnnotationContext(980 self.client, fixture1.get_target(), cfg=fixture1.get_cfg(),981 options=options)982 ctx.parse()983 ctx.write_to_ode(loops=10, ms=250)984 if ns == NSBULKANNOTATIONS:985 assert len(fixture1.get_child_annotations()) == 8986 assert len(fixture2.get_child_annotations()) == 16987 assert len(fixture2.get_all_map_annotations()) == 12988 if ns == MAPR_NS_GENE:989 assert len(fixture1.get_child_annotations()) == 8990 assert len(fixture2.get_child_annotations()) == 16991 assert len(fixture2.get_all_map_annotations()) == 20992 if ns is None:993 assert len(fixture1.get_child_annotations()) == 0994 assert len(fixture2.get_child_annotations()) == 16995 assert len(fixture2.get_all_map_annotations()) == 12996 ctx = DeleteMapAnnotationContext(997 self.client, fixture2.get_target(), cfg=fixture2.get_cfg(),998 options=options)999 ctx.parse()1000 ctx.write_to_ode(loops=10, ms=250)1001 if ns == NSBULKANNOTATIONS:1002 assert len(fixture1.get_child_annotations()) == 81003 assert len(fixture1.get_child_annotations(MAPR_NS_GENE)) == 81004 assert len(fixture2.get_child_annotations()) == 81005 assert len(fixture2.get_child_annotations(MAPR_NS_GENE)) == 81006 assert len(fixture2.get_all_map_annotations()) == 41007 if ns == MAPR_NS_GENE:1008 assert len(fixture1.get_child_annotations()) == 81009 assert len(fixture1.get_child_annotations(NSBULKANNOTATIONS)) == 81010 assert len(fixture2.get_child_annotations()) == 81011 assert len(fixture2.get_child_annotations(NSBULKANNOTATIONS)) == 81012 assert len(fixture2.get_all_map_annotations()) == 161013 if ns is None:1014 assert len(fixture1.get_child_annotations()) == 01015 assert len(fixture2.get_child_annotations()) == 01016 assert len(fixture2.get_all_map_annotations()) == 01017 @mark.parametrize("ns", [None, NSBULKANNOTATIONS, MAPR_NS_GENE])1018 def testPopulateMetadataNsAnnsDedup(self, ns):1019 """1020 Similar to testPopulateMetadataNsAnns but use two plates, check1021 MapAnnotations aren't duplicated, and filter by namespace1022 """1023 fixture1 = Plate2WellsNs2()1024 fixture1.init(self)1025 self._test_parsing_context(fixture1, 2)1026 self._test_bulk_to_map_annotation_context(fixture1, 2)1027 fixture2 = Plate2WellsNs2()1028 fixture2.init(self)1029 self._test_parsing_context(fixture2, 2)1030 self._test_bulk_to_map_annotation_dedup(fixture1, fixture2, ns)1031 @mark.parametrize("ns", [None, NSBULKANNOTATIONS, MAPR_NS_GENE])1032 def testPopulateMetadataNsAnnsDedupDelete(self, ns):1033 """1034 Similar to testPopulateMetadataNsAnns but use two plates, check1035 MapAnnotations aren't duplicated, and delete by namespace1036 """1037 fixture1 = Plate2WellsNs2()1038 fixture1.init(self)1039 self._test_parsing_context(fixture1, 2)1040 self._test_bulk_to_map_annotation_context(fixture1, 2)1041 fixture2 = Plate2WellsNs2()1042 fixture2.init(self)1043 self._test_parsing_context(fixture2, 2)1044 self._test_bulk_to_map_annotation_dedup(fixture1, fixture2, None)1045 self._test_delete_map_annotation_context_dedup(1046 fixture1, fixture2, ns)1047@pythonminver1048class TestPopulateMetadataConfigFiles(TestPopulateMetadataHelperPerMethod):1049 def _init_fixture_attach_cfg(self):1050 fixture = Plate2Wells()1051 fixture.init(self)1052 target = fixture.get_target()1053 ofile = self.client.upload(fixture.get_cfg()).proxy()1054 link = PlateAnnotationLinkI()1055 link.parent = target.proxy()1056 link.child = FileAnnotationI()1057 link.child.ns = rstring(NSBULKANNOTATIONSCONFIG)1058 link.child.file = ofile1059 link = self.client.sf.getUpdateService().saveAndReturnObject(link)1060 return fixture1061 def _get_annotations_config(self, fixture):1062 anns = []1063 for ann in fixture.get_annotations():1064 if not isinstance(ann, FileAnnotationI):1065 pass1066 if unwrap(ann.getNs()) == NSBULKANNOTATIONS:1067 continue1068 assert unwrap(ann.ns) == NSBULKANNOTATIONSCONFIG1069 anns.append(ann)1070 return anns1071 @mark.parametrize("ns", [None, NSBULKANNOTATIONS, NSBULKANNOTATIONSCONFIG])1072 @mark.parametrize("attach", [True, False])1073 def test_delete_attach(self, ns, attach):1074 fixture = self._init_fixture_attach_cfg()1075 target = fixture.get_target()1076 before = self._get_annotations_config(fixture)1077 assert len(before) == 11078 options = {}1079 if ns:1080 options['ns'] = ns1081 ctx = DeleteMapAnnotationContext(1082 self.client, target, attach=attach, options=options)1083 ctx.parse()1084 ctx.write_to_ode()1085 after = self._get_annotations_config(fixture)1086 if attach and ns != NSBULKANNOTATIONS:1087 assert len(after) == 01088 else:1089 assert before[0].id == after[0].id1090 assert before[0].file.id == after[0].file.id1091class MockMeasurementCtx(AbstractMeasurementCtx):1092 def well_name_to_number(self, well):1093 m = re.match("(?P<COL>[a-z]+)(?P<ROW>\d+)",1094 well, re.IGNORECASE)1095 if not m:1096 raise Exception("Bad well: %s" % well)1097 col = m.group("COL").upper()1098 row = m.group("ROW")1099 row_num = int(row) - 11100 col_num = 01101 for c in col:1102 i = string.ascii_uppercase.find(c)1103 col_num += i + 11104 # wellnumber_from_colrow1105 numcols = self.analysis_ctx.numcols1106 return (col_num * numcols) + row_num1107 def parse(self):1108 provider = self.original_file_provider1109 data = provider.get_original_file_data(self.original_file)1110 try:1111 rows = list(csv.reader(data, delimiter=","))1112 finally:1113 data.close()1114 columns = [1115 ImageColumn("Image", "", list()),1116 RoiColumn("ROI", "", list()),1117 StringColumn("Type", "", 12, list()),1118 ]1119 for row in rows[1:]:1120 wellnumber = self.well_name_to_number(row[0])1121 image = self.analysis_ctx.\1122 image_from_wellnumber(wellnumber)1123 # TODO: what to do with the field?!1124 # field = int(row[1])1125 # image = images[field]1126 roi = RoiI()1127 shape = PointI()1128 shape.x = rdouble(float(row[2]))1129 shape.y = rdouble(float(row[3]))1130 shape.textValue = rstring(row[4])1131 roi.addShape(shape)1132 roi.image = image.proxy()1133 rid = self.update_service\1134 .saveAndReturnIds([roi])[0]1135 columns[0].values.append(image.id.val)1136 columns[1].values.append(rid)1137 columns[2].values.append(row[4])1138 return MeasurementParsingResult([columns])1139 def get_name(self, *args, **kwargs):1140 # Strip .csv1141 return self.original_file.name.val[:-4]1142 def parse_and_populate_roi(self, columns):1143 # Remove from interface1144 # Using this as a place to set file annotation1145 self.file_annotation =\1146 self.update_service.saveAndReturnObject(1147 self.file_annotation)1148 rois = columns[1].values1149 for roi in rois:1150 link = RoiAnnotationLinkI()1151 link.parent = RoiI(roi, False)1152 link.child = self.file_annotation.proxy()1153 self.update_service\1154 .saveObject(link)1155 def populate(self, columns):1156 self.update_table(columns)1157class MockPlateAnalysisCtx(AbstractPlateAnalysisCtx):1158 def __init__(self, images, original_files,1159 original_file_image_map,1160 plate_id, service_factory):1161 super(MockPlateAnalysisCtx, self).__init__(1162 images, original_files, original_file_image_map,1163 plate_id, service_factory1164 )1165 for original_file in original_files:1166 name = original_file.name.val1167 if name.endswith("csv"):1168 self.measurements[len(self.measurements)] = \1169 original_file1170 def is_this_type(klass, original_files):1171 for original_file in original_files:1172 name = unwrap(original_file.name)1173 if name.endswith(".csv"):1174 return True1175 is_this_type = classmethod(is_this_type)1176 def get_measurement_count(self):1177 return len(self.measurements)1178 def get_measurement_ctx(self, index):1179 sf = self.service_factory1180 provider = self.DEFAULT_ORIGINAL_FILE_PROVIDER(sf)1181 return MockMeasurementCtx(1182 self, sf, provider,1183 self.measurements[index], None)1184 def get_result_file_count(self, index):1185 return 11186class ROICSV(Fixture):1187 def __init__(self):1188 self.count = 11189 self.annCount = 21190 self.csvName = self.createCsv(1191 colNames="Well,Field,X,Y,Type",1192 rowData=("A1,0,15,15,Test",))1193 self.rowCount = 11194 self.colCount = 11195 self.plate = None1196 def get_target(self):1197 if not self.plate:1198 self.plate = self.createPlate(1199 self.rowCount, self.colCount)1200 return self.plate1201@pythonminver1202class TestPopulateRois(ITest):1203 def testPopulateRoisPlate(self):1204 """1205 Create a small csv file, use populate_roi.py to parse and1206 attach to Plate. Then query to check table has expected content.1207 """1208 fixture = ROICSV()1209 fixture.init(self)1210 plate = fixture.get_target()1211 # As opposed to the ParsingContext, here we are expected1212 # to link the file ourselves1213 ofile = self.client.upload(fixture.csvName).proxy()1214 ann = FileAnnotationI()1215 ann.file = ofile1216 link = PlateAnnotationLinkI()1217 link.parent = plate.proxy()1218 link.child = ann1219 link = self.client.sf.getUpdateService()\1220 .saveAndReturnObject(link)1221 # End linking1222 factory = PlateAnalysisCtxFactory(self.client.sf)1223 factory.implementations = (MockPlateAnalysisCtx,)1224 ctx = factory.get_analysis_ctx(plate.id.val)1225 assert 1 == ctx.get_measurement_count()1226 meas = ctx.get_measurement_ctx(0)1227 meas.parse_and_populate()1228 # Get file annotations1229 query = """select p from Plate p1230 left outer join fetch p.annotationLinks links1231 left outer join fetch links.child as ann1232 left outer join fetch ann.file as file1233 where p.id=%s""" % plate.id.val1234 qs = self.client.sf.getQueryService()1235 plate = qs.findByQuery(query, None)1236 anns = plate.linkedAnnotationList()1237 # Only expect a single annotation which is a 'bulk annotation'1238 # the other is the original CSV1239 assert len(anns) == 21240 files = dict(1241 [(a.ns.val, a.file.id.val) for a in anns if a.ns])1242 fileid = files[NSMEASUREMENT]1243 # Open table to check contents1244 r = self.client.sf.sharedResources()1245 t = r.openTable(OriginalFileI(fileid), None)1246 cols = t.getHeaders()1247 rows = t.getNumberOfRows()1248 assert rows == 11249 data = t.read(range(len(cols)), 0, 1)1250 imag = data.columns[0].values[0]1251 rois = self.client.sf.getRoiService()1252 anns = rois.getRoiMeasurements(imag, RoiOptions())...
test_environment_resource.py
Source:test_environment_resource.py
1"""2Tests for EnvironmentResource api.3"""4from tests.case.api.crud import ApiCrudCases5import logging6logger = logging.getLogger("moztrap.test")7class EnvironmentResourceTest(ApiCrudCases):8 @property9 def factory(self):10 """The model factory for this object."""11 return self.F.EnvironmentFactory()12 @property13 def resource_name(self):14 return "environment"15 @property16 def permission(self):17 """The permissions needed to modify this object type."""18 return "environments.manage_environments"19 @property20 def new_object_data(self):21 """Generates a dictionary containing the field names and auto-generated22 values needed to create a unique object.23 The output of this method can be sent in the payload parameter of a24 POST message.25 """26 self.profile_fixture = self.F.ProfileFactory()27 self.category_fixture1 = self.F.CategoryFactory(name="A")28 self.category_fixture2 = self.F.CategoryFactory(name="B")29 self.category_fixture3 = self.F.CategoryFactory(name="C")30 self.element_fixture1 = self.F.ElementFactory(category=self.category_fixture1, name="A 2")31 self.element_fixture2 = self.F.ElementFactory(category=self.category_fixture2, name="B 2")32 self.element_fixture3 = self.F.ElementFactory(category=self.category_fixture3, name="C 2")33 self.element_fixture_list = [34 self.element_fixture1, self.element_fixture2, self.element_fixture3]35 return {36 u"profile": unicode(37 self.get_detail_url("profile", str(self.profile_fixture.id))),38 u"elements": [unicode(39 self.get_detail_url(40 "element", str(elem.id))41 ) for elem in self.element_fixture_list],42 }43 def backend_object(self, id):44 """Returns the object from the backend, so you can query it's values in45 the database for validation.46 """47 return self.model.Environment.everything.get(id=id)48 def backend_data(self, backend_obj):49 """Query's the database for the object's current values. Output is a50 dictionary that should match the result of getting the object's detail51 via the API, and can be used to verify API output.52 Note: both keys and data should be in unicode53 """54 return {55 u"id": backend_obj.id,56 u"profile": unicode(self.get_detail_url("profile", str(backend_obj.profile.id))),57 u"elements": [unicode(58 self.get_detail_url("element", str(elem.id))59 ) for elem in backend_obj.elements.all()],60 u"resource_uri": unicode(61 self.get_detail_url(self.resource_name, str(backend_obj.id))),62 }63 def test_elements_must_be_from_different_categories(self):64 """A post with two elements from the same category should error."""65 logger.info("test_elements_must_be_from_different_categories")66 # get data for creation & munge it67 fields = self.new_object_data68 self.element_fixture2.category = self.element_fixture1.category69 self.element_fixture2.save()70 # do the create71 res = self.post(72 self.get_list_url(self.resource_name),73 params=self.credentials,74 payload=fields,75 status=400,76 )77 error_msg = "Elements must each belong to a different Category."78 self.assertEqual(res.text, error_msg)79 def test_basic_combinatorics_patch(self):80 """A Patch request with profile and categories should do combinatorics81 on the categories and create environments."""82 logger.info("test_basic_combinatorics_patch")83 fields = self.new_object_data84 # create more elements for each category85 for x in range(2):86 self.F.ElementFactory(category=self.category_fixture1, name="A %s" % x)87 self.F.ElementFactory(category=self.category_fixture2, name="B %s" % x)88 self.F.ElementFactory(category=self.category_fixture3, name="C %s" % x)89 # modify fields to send categories rather than elements90 fields.pop('elements')91 fields['categories'] = [92 unicode(self.get_detail_url(93 "category", str(self.category_fixture1.id))),94 unicode(self.get_detail_url(95 "category", str(self.category_fixture2.id))),96 unicode(self.get_detail_url(97 "category", str(self.category_fixture3.id))),98 ]99 # do the create100 res = self.patch(101 self.get_list_url(self.resource_name),102 params=self.credentials,103 payload=fields,104 )105 # check that it made the right number of environments106 self._test_filter_list_by(u'profile', self.profile_fixture.id, 27)107 def test_patch_without_categories_error(self):108 """'categories' must be provided in PATCH."""109 logger.info("test_patch_without_categories_error")110 fields = self.new_object_data111 # do the create112 res = self.patch(113 self.get_list_url(self.resource_name),114 params=self.credentials,115 payload=fields,116 status=400,117 )118 error_msg = "PATCH request must contain categories list."119 self.assertEqual(res.text, error_msg)120 def test_patch_categories_not_list_error(self):121 """'categories' must be a list in PATCH."""122 logger.info("test_patch_categories_not_list_error")123 fields = self.new_object_data124 fields.pop("elements")125 fields[u'categories'] = unicode(126 self.get_detail_url("category", str(self.category_fixture1.id)))127 # do the create128 res = self.patch(129 self.get_list_url(self.resource_name),130 params=self.credentials,131 payload=fields,132 status=400,133 )134 error_msg = "PATCH request must contain categories list."135 self.assertEqual(res.text, error_msg)136 def test_patch_categories_list_not_string_or_hash_error(self):137 """'categories' must be a list in PATCH."""138 logger.info("test_patch_categories_list_not_string_or_hash_error")139 fields = self.new_object_data140 fields.pop("elements")141 fields[u'categories'] = [1, 2, 3]142 # do the create143 res = self.patch(144 self.get_list_url(self.resource_name),145 params=self.credentials,146 payload=fields,147 status=400,148 )149 error_msg = "categories list must contain resource uris or hashes."150 self.assertEqual(res.text, error_msg)151 def test_patch_with_exclude(self):152 """Combinatorics excluding some elements."""153 logger.info("test_patch_with_exclude")154 fields = self.new_object_data155 # create more elements for each category156 for x in range(2):157 self.F.ElementFactory(category=self.category_fixture1, name="A %s" % x)158 self.F.ElementFactory(category=self.category_fixture2, name="B %s" % x)159 self.F.ElementFactory(category=self.category_fixture3, name="C %s" % x)160 # modify fields to send categories rather than elements161 fields.pop('elements')162 fields['categories'] = [163 {164 u'category': unicode(self.get_detail_url(165 "category", str(self.category_fixture1.id))),166 u'exclude': [unicode(self.get_detail_url(167 "element", str(self.element_fixture1.id))), ],168 },169 {170 u'category': unicode(self.get_detail_url(171 "category", str(self.category_fixture2.id))),172 u'exclude': [unicode(self.get_detail_url(173 "element", str(self.element_fixture2.id))), ],174 },175 {176 u'category': unicode(self.get_detail_url(177 "category", str(self.category_fixture3.id))),178 u'exclude': [unicode(self.get_detail_url(179 "element", str(self.element_fixture3.id))), ],180 }, ]181 # do the create182 res = self.patch(183 self.get_list_url(self.resource_name),184 params=self.credentials,185 payload=fields,186 )187 # check that it made the right number of environments188 self._test_filter_list_by(u'profile', self.profile_fixture.id, 8)189 def test_patch_with_include(self):190 """Combinatorics including some elements."""191 logger.info("test_patch_with_include")192 fields = self.new_object_data193 # create more elements for each category194 for x in range(2):195 self.F.ElementFactory(category=self.category_fixture1, name="A %s" % x)196 self.F.ElementFactory(category=self.category_fixture2, name="B %s" % x)197 self.F.ElementFactory(category=self.category_fixture3, name="C %s" % x)198 # modify fields to send categories rather than elements199 fields.pop('elements')200 fields['categories'] = [201 {202 u'category': unicode(self.get_detail_url(203 "category", str(self.category_fixture1.id))),204 u'include': [unicode(self.get_detail_url(205 "element", str(self.element_fixture1.id))), ],206 },207 {208 u'category': unicode(self.get_detail_url(209 "category", str(self.category_fixture2.id))),210 u'include': [unicode(self.get_detail_url(211 "element", str(self.element_fixture2.id))), ],212 },213 {214 u'category': unicode(self.get_detail_url(215 "category", str(self.category_fixture3.id))),216 u'include': [unicode(self.get_detail_url(217 "element", str(self.element_fixture3.id))), ],218 }, ]219 # do the create220 res = self.patch(221 self.get_list_url(self.resource_name),222 params=self.credentials,223 payload=fields,224 )225 # check that it made the right number of environments226 self._test_filter_list_by(u'profile', self.profile_fixture.id, 1)227 def test_patch_no_include_no_exclude(self):228 """Sending hashes without include or exclude should do the same as229 sending regular uri strings."""230 logger.info("test_patch_no_include_no_exclude")231 fields = self.new_object_data232 # create more elements for each category233 for x in range(2):234 self.F.ElementFactory(category=self.category_fixture1, name="A %s" % x)235 self.F.ElementFactory(category=self.category_fixture2, name="B %s" % x)236 self.F.ElementFactory(category=self.category_fixture3, name="C %s" % x)237 # modify fields to send categories rather than elements238 fields.pop('elements')239 fields['categories'] = [240 {241 u'category': unicode(self.get_detail_url(242 "category", str(self.category_fixture1.id))),243 },244 {245 u'category': unicode(self.get_detail_url(246 "category", str(self.category_fixture2.id))),247 },248 {249 u'category': unicode(self.get_detail_url(250 "category", str(self.category_fixture3.id))),251 }, ]252 # do the create253 res = self.patch(254 self.get_list_url(self.resource_name),255 params=self.credentials,256 payload=fields,257 )258 # check that it made the right number of environments...
Cinematic.spec.js
Source:Cinematic.spec.js
1/* eslint-env jasmine */2import {3 getLeftCharacterThangTypeSlug,4 getRightCharacterThangTypeSlug,5 getLeftHero,6 getRightHero,7 getClearBackgroundObject,8 getBackgroundObject,9 getBackgroundObjectDelay,10 getBackground,11 getClearText,12 getSpeaker,13 getBackgroundSlug,14 getExitCharacter,15 getTextPosition,16 getText,17 getCamera,18 getTextAnimationLength,19 getSpeakingAnimationAction,20 getSetupMusic,21 getSoundEffects,22 getWaitUserInput,23 getLanguageFilter,24 getHeroPet25} from '../../../app/schemas/models/selectors/cinematic'26/**27 * This data can be used to check that none of the selectors that match28 * the left or right character work.29 * Intentionally invalid data.30 */31const invalidThangTypesSetupData = [32 { shotSetup: {} },33 { dialogNodes: [] },34 { shotSetup: { camera: 'dual' } },35 { shotSetup: { rightThangType: {} } },36 { shotSetup: { backgroundArt: {} } },37 { shotSetup: { leftThangType: undefined } },38 { shotSetup: { leftThangType: { slug: 'abc', rand: 123 } } },39 { shotSetup: { rightThangType: undefined } },40 { shotSetup: { rightThangType: { slug: 'abc', rand: 123 } } }41]42describe('Cinematic', () => {43 describe('Selectors', () => {44 getCharacterThangTypeSlugTest(getLeftCharacterThangTypeSlug, 'getLeftCharacterThangTypeSlug', invalidThangTypesSetupData, 'leftThangType')45 getCharacterThangTypeSlugTest(getRightCharacterThangTypeSlug, 'getRightCharacterThangTypeSlug', invalidThangTypesSetupData, 'rightThangType')46 it('getLeftCharacterThangTypeSlug', () => {47 const result = getLeftCharacterThangTypeSlug(shotFixture1)48 expect(result).toBeUndefined()49 const result2 = getLeftCharacterThangTypeSlug(shotFixture2)50 expect(result2).toEqual({ slug: 'fake-slug-thangtype', enterOnStart: false, thang: { scaleX: 1.2, scaleY: 1.2, pos: { x: -30, y: -72 } } })51 })52 it('getRightCharacterThangTypeSlug', () => {53 const result = getRightCharacterThangTypeSlug(shotFixture2)54 expect(result).toBeUndefined()55 const result2 = getRightCharacterThangTypeSlug(shotFixture1)56 expect(result2).toEqual({ slug: 'fake-slug-thangtype', enterOnStart: false, thang: { scaleX: 1.2, scaleY: 1.2, pos: { x: 30, y: -72 } } })57 })58 it('getLeftHero', () => {59 const result = getLeftHero(shotFixture1)60 expect(result).toEqual({ enterOnStart: true, thang: { scaleX: 1, scaleY: 13, pos: { x: 3, y: 10 } } })61 const result2 = getLeftHero(shotFixture2)62 expect(result2).toBeUndefined()63 })64 it('getRightHero', () => {65 const result = getRightHero(shotFixture2)66 expect(result).toEqual({ enterOnStart: true, thang: { scaleX: 1, scaleY: 13, pos: { x: 3, y: 10 } } })67 const result2 = getRightHero(shotFixture1)68 expect(result2).toBeUndefined()69 })70 it('getClearBackgroundObject', () => {71 const result = getClearBackgroundObject(shotFixture1.dialogNodes[0])72 expect(result).toEqual(7331)73 const result2 = getClearBackgroundObject(shotFixture2.dialogNodes[0])74 expect(result2).toBeUndefined()75 })76 it('getBackgroundObject', () => {77 const result = getBackgroundObject(shotFixture1.dialogNodes[0])78 expect(result).toEqual({ scaleX: 1, scaleY: 1, pos: { x: 0, y: 0 }, type: { slug: 'background-obj-fixture' } })79 const result2 = getBackgroundObject(shotFixture2.dialogNodes[0])80 expect(result2).toBeUndefined()81 })82 it('getBackgroundObjectDelay', () => {83 const result = getBackgroundObjectDelay(shotFixture1.dialogNodes[0])84 expect(result).toEqual(1337)85 const result2 = getBackgroundObjectDelay(shotFixture2.dialogNodes[0])86 expect(result2).toBeUndefined()87 })88 it('getBackground', () => {89 const result = getBackground(shotFixture1)90 expect(result).toEqual({ slug: 'background-fixture-slug', thang: { scaleX: 0.3, scaleY: 0.2, pos: { x: 17, y: 18 } } })91 const result2 = getBackground(shotFixture2)92 expect(result2).toBeUndefined()93 })94 it('getClearText', () => {95 const result = getClearText(shotFixture1.dialogNodes[0])96 expect(result).toEqual(false)97 const result2 = getClearText(shotFixture2.dialogNodes[0])98 expect(result2).toEqual(true)99 })100 it('getSpeaker', () => {101 const result = getSpeaker(shotFixture1.dialogNodes[0])102 expect(result).toEqual('left')103 const result2 = getSpeaker(shotFixture2.dialogNodes[0])104 expect(result2).toEqual('right')105 })106 it('getBackgroundSlug', () => {107 const result = getBackgroundSlug(shotFixture1)108 expect(result).toEqual('background-fixture-slug')109 const result2 = getBackgroundSlug(shotFixture2)110 expect(result2).toBeUndefined()111 })112 it('getExitCharacter', () => {113 const result = getExitCharacter(shotFixture1.dialogNodes[0])114 expect(result).toEqual('both')115 const result2 = getExitCharacter(shotFixture2.dialogNodes[0])116 expect(result2).toBeUndefined()117 })118 it('getTextPosition', () => {119 const result = getTextPosition(shotFixture1.dialogNodes[0])120 expect(result).toBeUndefined()121 const result2 = getTextPosition(shotFixture2.dialogNodes[0])122 expect(result2).toEqual({123 x: 40,124 y: 10125 })126 })127 it('getText', () => {128 const result = getText(shotFixture1.dialogNodes[0])129 expect(result).toEqual('hello, world')130 const result2 = getText(shotFixture2.dialogNodes[0])131 expect(result2).toBeUndefined()132 })133 it('getCamera', () => {134 const result = getCamera(shotFixture1)135 expect(result).toEqual({ pos: { x: 2, y: 0 }, zoom: 2 })136 const result2 = getCamera(shotFixture2)137 expect(result2).toBeUndefined()138 expect(getCamera(undefined)).toBeUndefined()139 })140 it('getTextAnimationLength', () => {141 const result = getTextAnimationLength(shotFixture1.dialogNodes[1])142 expect(result).toEqual(42)143 const result2 = getTextAnimationLength(shotFixture2.dialogNodes[0])144 expect(result2).toBeUndefined()145 })146 it('getSpeakingAnimationAction', () => {147 const result = getSpeakingAnimationAction(shotFixture1.dialogNodes[1])148 expect(result).toEqual('talkyAnimation')149 const result2 = getSpeakingAnimationAction(shotFixture2.dialogNodes[0])150 expect(result2).toBeUndefined()151 })152 it('getSoundEffects', () => {153 const result = getSoundEffects(shotFixture1.dialogNodes[0])154 expect(result).toEqual([ { sound: { mp3: 'path/music' }, triggerStart: 0 } ])155 const result2 = getSoundEffects(shotFixture2.dialogNodes[0])156 expect(result2).toEqual([ { sound: { mp3: 'path/music' }, triggerStart: 30 } ])157 })158 it('getSetupMusic', () => {159 const result = getSetupMusic(shotFixture1)160 expect(result).toEqual({ ogg: 'path/music', mp3: 'path/music/mp3' })161 const result2 = getSetupMusic(shotFixture2)162 expect(result2).toBeUndefined()163 })164 it('getWaitUserInput', () => {165 expect(getWaitUserInput({ waitUserInput: false })).toEqual(false)166 expect(getWaitUserInput({})).toEqual(true)167 expect(getWaitUserInput()).toEqual(true)168 expect(getWaitUserInput({ waitUserInput: true })).toEqual(true)169 })170 it('getLanguageFilter', () => {171 expect(getLanguageFilter({})).toBeUndefined()172 expect(getLanguageFilter()).toBeUndefined()173 expect(getLanguageFilter({ programmingLanguageFilter: 'python' })).toEqual('python')174 expect(getLanguageFilter({ programmingLanguageFilter: 'javascript' })).toEqual('javascript')175 })176 it('getHeroPet', () => {177 const result = getHeroPet(shotFixture1)178 expect(result).toEqual({ slug: 'hero-dog-slug', thang: { scaleX: 1, scaleY: 2, pos: { x: 2, y: 0 } } })179 const result2 = getHeroPet(shotFixture2)180 expect(result2).toBeUndefined()181 })182 })183})184// Test for left and right character selectors.185function getCharacterThangTypeSlugTest (selector, side, data, characterProperty) {186 describe(`${side}`, () => {187 it('returns undefined when passed nothing', () => {188 expect(selector(undefined)).toBeUndefined()189 })190 it('returns undefined if the left thangType doesn\'t have type', () => {191 for (const testData of data) {192 expect(selector(testData)).toBeUndefined()193 }194 })195 })196}197// Fixture testing selectors for cinematics.198var shotFixture1 = {199 shotSetup: {200 leftThangType: {201 thangType: {202 type: 'hero',203 pos: {204 x: 3,205 y: 10206 },207 scaleX: 1,208 scaleY: 13209 },210 enterOnStart: true211 },212 rightThangType: {213 thangType: {214 type: {215 slug: 'fake-slug-thangtype'216 }217 }218 },219 heroPetThangType: {220 type: {221 slug: 'hero-dog-slug'222 },223 pos: {224 x: 2225 },226 scaleY: 2227 },228 backgroundArt: {229 type: {230 slug: 'background-fixture-slug'231 },232 pos: {233 x: 17,234 y: 18235 },236 scaleX: 0.3,237 scaleY: 0.2238 },239 camera: {240 pos: {241 x: 2242 },243 zoom: 2244 },245 music: {246 ogg: 'path/music',247 mp3: 'path/music/mp3'248 }249 },250 dialogNodes: [251 {252 dialogClear: false,253 exitCharacter: 'both',254 text: 'hello, world',255 triggers: {256 backgroundObject: {257 thangType: {258 type: {259 slug: 'background-obj-fixture'260 }261 },262 triggerStart: 1337263 },264 clearBackgroundObject: {265 triggerStart: 7331266 },267 soundFxTriggers: [268 {269 sound: {270 mp3: 'path/music'271 }272 }273 ]274 }275 },276 {277 dialogClear: false,278 textAnimationLength: 42,279 speakingAnimationAction: 'talkyAnimation'280 }281 ]282}283var shotFixture2 = {284 shotSetup: {285 rightThangType: {286 thangType: {287 type: 'hero',288 pos: {289 x: 3,290 y: 10291 },292 scaleX: 1,293 scaleY: 13294 },295 enterOnStart: true296 },297 leftThangType: {298 thangType: {299 type: {300 slug: 'fake-slug-thangtype'301 }302 }303 }304 },305 dialogNodes: [306 {307 speaker: 'right',308 triggers: {309 soundFxTriggers: [310 {311 sound: {312 mp3: 'path/music'313 },314 triggerStart: 30315 }316 ]317 },318 textLocation: {319 x: 40,320 y: 10321 }322 }323 ]...
extract_google_test_list_test.py
Source:extract_google_test_list_test.py
1# Copyright 2014 The Chromium Authors. All rights reserved.2# Use of this source code is governed by a BSD-style license that can be3# found in the LICENSE file.4import StringIO5import unittest6from src.build.util.test import extract_google_test_list7class TestExtractGoogleTestList(unittest.TestCase):8 def _parse_cpp_test_list(self, content):9 """Simple wrapper of _parse_test_list for C++ testing."""10 return extract_google_test_list._parse_test_list(11 StringIO.StringIO(content),12 extract_google_test_list._CPP_TEST_METHOD_PATTERN)13 def test_parser_cpp_test_list(self):14 # Simple cases for TEST_F.15 self.assertEquals(16 ['Fixture1#test_method1',17 'Fixture1#test_method2',18 'Fixture2#test_method1',19 'Fixture2#test_method2'],20 self._parse_cpp_test_list('\n'.join([21 'TEST_F(Fixture1, test_method1) {',22 ' // test body',23 '}',24 '',25 'TEST_F(Fixture1, test_method2) {',26 ' // test body',27 '}',28 '',29 'TEST_F(Fixture2, test_method1) {',30 ' // test body',31 '}',32 '',33 'TEST_F(Fixture2, test_method2) {',34 ' // test body',35 '}'])))36 # Simple cases for TEST.37 self.assertEquals(38 ['Fixture1#test_method1',39 'Fixture1#test_method2',40 'Fixture2#test_method1',41 'Fixture2#test_method2'],42 self._parse_cpp_test_list('\n'.join([43 'TEST(Fixture1, test_method1) {',44 ' // test body',45 '}',46 '',47 'TEST(Fixture1, test_method2) {',48 ' // test body',49 '}',50 '',51 'TEST(Fixture2, test_method1) {',52 ' // test body',53 '}',54 '',55 'TEST(Fixture2, test_method2) {',56 ' // test body',57 '}'])))58 # Line breaks around fixture and test name.59 self.assertEquals(60 ['Fixture1#test_method1',61 'Fixture1#test_method2',62 'Fixture1#test_method3'],63 self._parse_cpp_test_list('\n'.join([64 'TEST_F(Fixture1,'65 ' test_method1) {',66 ' // test body',67 '}',68 '',69 'TEST_F('70 ' Fixture1, test_method2) {',71 ' // test body',72 '}',73 '',74 'TEST_F('75 ' Fixture1,'76 ' test_method3) {',77 ' // test body',78 '}'])))79 def _parse_javascript_test_list(self, content):80 """Simple wrapper of _parse_test_list for JavaScript testing."""81 return extract_google_test_list._parse_test_list(82 StringIO.StringIO(content),83 extract_google_test_list._JAVASCRIPT_TEST_METHOD_PATTERN)84 def test_parse_javascript_test_list(self):85 # Simple cases.86 self.assertEquals(87 ['Fixture1#test_method1',88 'Fixture1#test_method2',89 'Fixture2#test_method1',90 'Fixture2#test_method2'],91 self._parse_javascript_test_list('\n'.join([92 'TEST_F(Fixture1, "test_method1", function() {',93 ' // Some test body code;',94 '});',95 '',96 'TEST_F(Fixture1, "test_method2", function() {',97 ' // Some test body code;',98 '});',99 '',100 'TEST_F(Fixture2, "test_method1", function() {',101 ' // Some test body code;',102 '});',103 '',104 'TEST_F(Fixture2, "test_method2", function() {',105 ' // Some test body code;',106 '});',107 ''])))108 # Some line breaks around the parameters.109 self.assertEquals(110 ['Fixture1#test_method1',111 'Fixture1#test_method2',112 'Fixture1#test_method3',113 'Fixture1#test_method4'],114 self._parse_javascript_test_list('\n'.join([115 'TEST_F(Fixture1, "test_method1",',116 ' function() {',117 ' // Some test body code;',118 '});',119 '',120 'TEST_F(Fixture1,',121 ' "test_method2", function() {',122 ' // Some test body code;',123 '});',124 '',125 'TEST_F(',126 ' Fixture1, "test_method3", function() {',127 ' // Some test body code;',128 '});',129 '',130 'TEST_F(',131 ' Fixture1,',132 ' "test_method4",',133 ' function() {',134 ' // Some test body code;',135 '});',136 ''])))137 # The definition of TEST_F should not be included.138 self.assertEquals(139 [],140 self._parse_javascript_test_list('\n'.join([141 'function TEST_F(fixtureClass, testName, '142 'testFunc, opt_caseName) {',143 ' // The definition code line 1.',144 ' // The definition code line 2.',145 ' // The definition code line 3.',146 '}'])))147if __name__ == '__main__':...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!