11"""Test citations."""
2+
23import pytest
34
45from .. import api
56
67
8+ class Bibtex :
9+ def __init__ (self , bibtex ):
10+ self .text = bibtex
11+ self .url_only = False
12+ self .etype = None
13+ self .citekey = None
14+ self .pairs = {}
15+
16+ # DOI could not be converted
17+ if self .text .startswith ("http" ):
18+ self .url_only = True
19+ else :
20+ self ._parse_bibtex ()
21+
22+ def _parse_bibtex (self ):
23+ import re
24+
25+ try :
26+ self .etype = re .search (r"@(\w+)" , self .text ).group (1 )
27+ except AttributeError :
28+ raise TypeError (f"Invalid bibtex: { self .text } " )
29+ try :
30+ self .citekey = re .search (r"@[^{]*{([^,\s]+)" , self .text ).group (1 )
31+ except AttributeError :
32+ raise TypeError (f"Invalid bibtex: { self .text } " )
33+ self .pairs = {
34+ key : val for key , val in re .findall (r"(\w+)=(\{[^{}]+\})" , self .text )
35+ }
36+
37+ def get (self , val ):
38+ return self .pairs .get (val )
39+
40+ def __str__ (self ):
41+ return self .text
42+
43+ def __repr__ (self ):
44+ return f'@{ self .etype } {{{ self .citekey } , { ", " .join ([f"{ key } = { val } " for key , val in self .pairs .items ()])} }}'
45+
46+ def __eq__ (self , other ):
47+ if isinstance (other , Bibtex ):
48+ if self .url_only and self .text == other .text :
49+ return True
50+ if (
51+ self .etype == other .etype
52+ and self .citekey == other .citekey
53+ and self .pairs == other .pairs
54+ ):
55+ return True
56+ return False
57+
58+ def assert_same (self , other ):
59+ """Convenience method to find deviations between two Bibtex objects"""
60+ assert isinstance (other , Bibtex )
61+ assert self .etype == other .etype , "Mismatched entry types"
62+ assert self .citekey == other .citekey , "Mismatched citekeys"
63+ for key in self .pairs .keys ():
64+ assert key in other .pairs , f"Key ({ key } ) missing from other"
65+ assert (
66+ self .pairs [key ] == other .pairs [key ]
67+ ), f"Key ({ key } ) mismatched\n \n { self .pairs [key ]} \n \n { other .pairs [key ]} "
68+
69+ for key in other .pairs .keys ():
70+ assert key in self .pairs , f"Key ({ key } ) missing from pairs"
71+
72+ assert self .pairs == other .pairs , "Dictionaries do not match"
73+
74+
775# test setup to avoid cluttering pytest parameterize
876mni2009_urls = [
977 "https://doi.org/10.1016/j.neuroimage.2010.07.033" ,
1482
1583mni2009_fbib = """\
1684 @article{Fonov_2011,
17- \t doi = {10.1016/j.neuroimage.2010.07.033},
18- \t url = {https://doi.org/10.1016%2Fj .neuroimage.2010.07.033},
19- \t year = 2011,
20- \t month = {jan },
21- \t publisher = {Elsevier {BV} },
22- \t volume = {54},
23- \t number = {1},
24- \t pages = {313-- 327},
25- \t author = {Vladimir Fonov and Alan C. Evans and Kelly Botteron and C. Robert \
26- Almli and Robert C. McKinstry and D. Louis Collins },
27- \t title = {Unbiased average age-appropriate atlases for pediatric studies},
28- \t journal = {{ NeuroImage} }
85+ DOI= {10.1016/j.neuroimage.2010.07.033},
86+ url= {https://doi.org/10.1016/j .neuroimage.2010.07.033},
87+ year={ 2011} ,
88+ publisher={Elsevier BV },
89+ ISSN={1053-8119 },
90+ volume= {54},
91+ number= {1},
92+ pages= {313– 327},
93+ author={ Fonov, Vladimir and Evans, Alan C. and Botteron, Kelly and Almli, C. Robert \
94+ and McKinstry, Robert C. and Collins, D. Louis},
95+ title= {Unbiased average age-appropriate atlases for pediatric studies},
96+ journal={ NeuroImage}
2997}"""
3098
3199mni2009_lbib = """\
32- @incollection{Collins_1999,
33- \t doi = {10.1007/3-540-48714-x_16},
34- \t url = {https://doi.org/10.1007%2F3-540-48714-x_16},
35- \t year = 1999,
36- \t publisher = {Springer Berlin Heidelberg},
37- \t pages = {210--223},
38- \t author = {D. Louis Collins and Alex P. Zijdenbos and Wim F. C. Baar{\\ '{e}} and Alan C. Evans},
39- \t title = {{ANIMAL}$\\ mathplus${INSECT}: Improved Cortical Structure Segmentation},
40- \t booktitle = {Lecture Notes in Computer Science}
100+ @inbook{Collins_1999,
101+ DOI={10.1007/3-540-48714-x_16},
102+ url={https://doi.org/10.1007/3-540-48714-X_16},
103+ year={1999},
104+ publisher={Springer Berlin Heidelberg},
105+ pages={210–223},
106+ ISBN={9783540487142},
107+ ISSN={0302-9743}
108+ author={Collins, D. Louis and Zijdenbos, Alex P. and Baaré, Wim F. C. and Evans, Alan C.},
109+ title={ANIMAL+INSECT: Improved Cortical Structure Segmentation},
110+ booktitle={Information Processing in Medical Imaging}
41111}"""
42112
43113fslr_urls = [
47117
48118fslr_fbib = """\
49119 @article{Van_Essen_2011,
50- \t doi = {10.1093/cercor/bhr291},
51- \t url = {https://doi.org/10.1093%2Fcercor%2Fbhr291 },
52- \t year = 2011 ,
53- \t month = {nov },
54- \t publisher = {Oxford University Press ({ OUP} )},
55- \t volume = {22},
56- \t number = {10},
57- \t pages = {2241-- 2262},
58- \t author = { D. C. Van Essen and M. F. Glasser and D. L. Dierker and J. Harwell and T. Coalson },
59- \t title = {Parcellations and Hemispheric Asymmetries of Human Cerebral Cortex Analyzed on \
120+ DOI= {10.1093/cercor/bhr291},
121+ ISSN={1460-2199 },
122+ url={https://doi.org/10.1093/cercor/bhr291} ,
123+ year={2011 },
124+ publisher= {Oxford University Press (OUP)},
125+ volume= {22},
126+ number= {10},
127+ pages= {2241– 2262},
128+ author={Van Essen, D. C. and Glasser, M. F. and Dierker, D. L. and Harwell, J. and Coalson, T. },
129+ title= {Parcellations and Hemispheric Asymmetries of Human Cerebral Cortex Analyzed on \
60130 Surface-Based Atlases},
61- \t journal = {Cerebral Cortex}
131+ journal= {Cerebral Cortex}
62132}"""
63133
64134fslr_lbib = (
67137
68138fsaverage_fbib = """\
69139 @article{Fischl_1999,
70- \t doi = {10.1002/(sici)1097-0193(1999)8:4<272::aid-hbm10>3.0.co;2-4},
71- \t url = {https://doi.org/10.1002%2F%28sici%291097-0193%281999%298%3A4%3C272%3A%3Aaid-hbm10%3E3.0.co%3B2-4},
72- \t year = 1999,
73- \t publisher = {Wiley},
74- \t volume = {8},
75- \t number = {4},
76- \t pages = {272--284},
77- \t author = {Bruce Fischl and Martin I. Sereno and Roger B.H. Tootell and Anders M. Dale},
78- \t title = {High-resolution intersubject averaging and a coordinate system for the cortical surface},
79- \t journal = {Human Brain Mapping}
140+ DOI={10.1002/(sici)1097-0193(1999)8:4<272::aid-hbm10>3.0.co;2-4},
141+ ISSN={1097-0193},
142+ url={https://doi.org/10.1002/(sici)1097-0193(1999)8:4<272::aid-hbm10>3.0.co;2-4},
143+ year={1999},
144+ publisher={Wiley},
145+ volume={8},
146+ number={4},
147+ pages={272–284},
148+ author={Fischl, Bruce and Sereno, Martin I. and Tootell, Roger B.H. and Dale, Anders M.},
149+ title={High-resolution intersubject averaging and a coordinate system for the cortical surface},
150+ journal={Human Brain Mapping}
80151}"""
81152
153+
82154@pytest .mark .parametrize (
83155 "template,urls,fbib,lbib" ,
84156 [
85157 ("MNI152NLin2009cAsym" , mni2009_urls , mni2009_fbib , mni2009_lbib ),
86158 ("fsLR" , fslr_urls , fslr_fbib , fslr_lbib ),
87- ("fsaverage" , ["https://doi.org/10.1002/(sici)1097-0193(1999)8:4%3C272::aid-hbm10%3E3.0.co;2-4" ], fsaverage_fbib , None ),
159+ (
160+ "fsaverage" ,
161+ [
162+ "https://doi.org/10.1002/(sici)1097-0193(1999)8:4%3C272::aid-hbm10%3E3.0.co;2-4"
163+ ],
164+ fsaverage_fbib ,
165+ None ,
166+ ),
88167 ],
89168)
90169def test_citations (tmp_path , template , urls , fbib , lbib ):
91170 """Check the correct composition of citations."""
92171 assert api .get_citations (template ) == urls
93172 bibs = api .get_citations (template , bibtex = True )
94173 if bibs :
95- assert "" .join (bibs [0 ]) == fbib
96- assert len (bibs ) == 1 if lbib is None else "" .join (bibs [- 1 ]) == lbib
174+ bib0 = Bibtex (bibs [0 ])
175+ exp0 = Bibtex (fbib )
176+ assert bib0 == exp0
177+ if lbib is not None :
178+ bib1 = Bibtex (bibs [- 1 ])
179+ exp1 = Bibtex (lbib )
180+ assert bib1 == exp1
181+ else :
182+ assert len (bibs ) == 1
183+
97184 else :
98185 # no citations currently
99186 assert False
@@ -108,7 +195,7 @@ def test_pybids_magic_get():
108195
109196 with pytest .raises (TypeError ):
110197 api .ls_atlases ("MNI152NLin6ASym" )
111-
198+
112199 # Existing layout.get_* should not be bubbled to the layout
113200 # (that means, raise an AttributeError instead of a BIDSEntityError)
114201 with pytest .raises (AttributeError ):
0 commit comments