From 2078c2f671e924e09c76d4cd80002081786afce6 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 10 Nov 2021 18:58:48 -0500 Subject: [PATCH] docs: sample HTML report for 6.1.2 --- .../d_7b071bdc2a35fa80___init___py.html | 4 +- .../d_7b071bdc2a35fa80___main___py.html | 4 +- .../d_7b071bdc2a35fa80_backward_py.html | 4 +- .../d_7b071bdc2a35fa80_cogapp_py.html | 1535 ++++----- .../d_7b071bdc2a35fa80_makefiles_py.html | 4 +- .../d_7b071bdc2a35fa80_test_cogapp_py.html | 2822 +++++++++-------- .../d_7b071bdc2a35fa80_test_makefiles_py.html | 4 +- ...d_7b071bdc2a35fa80_test_whiteutils_py.html | 4 +- .../d_7b071bdc2a35fa80_whiteutils_py.html | 4 +- doc/sample_html/index.html | 32 +- doc/sample_html/status.json | 2 +- 11 files changed, 2232 insertions(+), 2187 deletions(-) diff --git a/doc/sample_html/d_7b071bdc2a35fa80___init___py.html b/doc/sample_html/d_7b071bdc2a35fa80___init___py.html index a947dfe6d..02ab6f19b 100644 --- a/doc/sample_html/d_7b071bdc2a35fa80___init___py.html +++ b/doc/sample_html/d_7b071bdc2a35fa80___init___py.html @@ -72,8 +72,8 @@

diff --git a/doc/sample_html/d_7b071bdc2a35fa80___main___py.html b/doc/sample_html/d_7b071bdc2a35fa80___main___py.html index 978855d87..b8c8069e6 100644 --- a/doc/sample_html/d_7b071bdc2a35fa80___main___py.html +++ b/doc/sample_html/d_7b071bdc2a35fa80___main___py.html @@ -68,8 +68,8 @@

diff --git a/doc/sample_html/d_7b071bdc2a35fa80_backward_py.html b/doc/sample_html/d_7b071bdc2a35fa80_backward_py.html index 7f99a5734..625b7f700 100644 --- a/doc/sample_html/d_7b071bdc2a35fa80_backward_py.html +++ b/doc/sample_html/d_7b071bdc2a35fa80_backward_py.html @@ -105,8 +105,8 @@

diff --git a/doc/sample_html/d_7b071bdc2a35fa80_cogapp_py.html b/doc/sample_html/d_7b071bdc2a35fa80_cogapp_py.html index 775dd4380..f8a35e08d 100644 --- a/doc/sample_html/d_7b071bdc2a35fa80_cogapp_py.html +++ b/doc/sample_html/d_7b071bdc2a35fa80_cogapp_py.html @@ -3,7 +3,7 @@ - Coverage for cogapp/cogapp.py: 49.42% + Coverage for cogapp/cogapp.py: 49.50% @@ -13,7 +13,7 @@

Coverage for cogapp/cogapp.py: - 49.42% + 49.50%

@@ -44,11 +44,11 @@

- 486 statements   - - + 495 statements   + + - +

@@ -83,7 +83,7 @@

22 

23__all__ = ['Cog', 'CogUsageError', 'main'] 

24 

-

25__version__ = '3.1.0' 

+

25__version__ = '3.2.0' 

26 

27usage = """\ 

28cog - generate content with inlined Python code. 

@@ -104,777 +104,790 @@

43 -o OUTNAME Write the output to OUTNAME. 

44 -p PROLOGUE Prepend the generator source with PROLOGUE. Useful to insert an 

45 import line. Example: -p "import math" 

-

46 -r Replace the input file with the output. 

-

47 -s STRING Suffix all generated output lines with STRING. 

-

48 -U Write the output with Unix newlines (only LF line-endings). 

-

49 -w CMD Use CMD if the output file needs to be made writable. 

-

50 A %s in the CMD will be filled with the filename. 

-

51 -x Excise all the generated output without running the generators. 

-

52 -z The end-output marker can be omitted, and is assumed at eof. 

-

53 -v Print the version of cog and exit. 

-

54 --verbosity=VERBOSITY 

-

55 Control the amount of output. 2 (the default) lists all files, 

-

56 1 lists only changed files, 0 lists no files. 

-

57 --markers='START END END-OUTPUT' 

-

58 The patterns surrounding cog inline instructions. Should 

-

59 include three values separated by spaces, the start, end, 

-

60 and end-output markers. Defaults to '[[[cog ]]] [[[end]]]'. 

-

61 -h Print this help. 

-

62""" 

-

63 

-

64# Other package modules 

-

65from .whiteutils import * 

-

66 

-

67class CogError(Exception): 

-

68 """ Any exception raised by Cog. 

-

69 """ 

-

70 def __init__(self, msg, file='', line=0): 

-

71 if file: 

-

72 Exception.__init__(self, "%s(%d): %s" % (file, line, msg)) 

-

73 else: 

-

74 Exception.__init__(self, msg) 

-

75 

-

76class CogUsageError(CogError): 

-

77 """ An error in usage of command-line arguments in cog. 

-

78 """ 

-

79 pass 

-

80 

-

81class CogInternalError(CogError): 

-

82 """ An error in the coding of Cog. Should never happen. 

-

83 """ 

-

84 pass 

-

85 

-

86class CogGeneratedError(CogError): 

-

87 """ An error raised by a user's cog generator. 

-

88 """ 

-

89 pass 

-

90 

-

91class CogUserException(CogError): 

-

92 """ An exception caught when running a user's cog generator. 

-

93 The argument is the traceback message to print. 

-

94 """ 

-

95 pass 

-

96 

-

97class Redirectable: 

-

98 """ An object with its own stdout and stderr files. 

-

99 """ 

-

100 def __init__(self): 

-

101 self.stdout = sys.stdout 

-

102 self.stderr = sys.stderr 

-

103 

-

104 def setOutput(self, stdout=None, stderr=None): 

-

105 """ Assign new files for standard out and/or standard error. 

-

106 """ 

-

107 if stdout: 107 ↛ 109line 107 didn't jump to line 109, because the condition on line 107 was never false

-

108 self.stdout = stdout 

-

109 if stderr: 109 ↛ 110line 109 didn't jump to line 110, because the condition on line 109 was never true

-

110 self.stderr = stderr 

-

111 

-

112 def prout(self, s, end="\n"): 

-

113 print(s, file=self.stdout, end=end) 

-

114 

-

115 def prerr(self, s, end="\n"): 

-

116 print(s, file=self.stderr, end=end) 

-

117 

+

46 -P Use print() instead of outl for code output. 

+

47 -r Replace the input file with the output. 

+

48 -s STRING Suffix all generated output lines with STRING. 

+

49 -U Write the output with Unix newlines (only LF line-endings). 

+

50 -w CMD Use CMD if the output file needs to be made writable. 

+

51 A %s in the CMD will be filled with the filename. 

+

52 -x Excise all the generated output without running the generators. 

+

53 -z The end-output marker can be omitted, and is assumed at eof. 

+

54 -v Print the version of cog and exit. 

+

55 --verbosity=VERBOSITY 

+

56 Control the amount of output. 2 (the default) lists all files, 

+

57 1 lists only changed files, 0 lists no files. 

+

58 --markers='START END END-OUTPUT' 

+

59 The patterns surrounding cog inline instructions. Should 

+

60 include three values separated by spaces, the start, end, 

+

61 and end-output markers. Defaults to '[[[cog ]]] [[[end]]]'. 

+

62 -h Print this help. 

+

63""" 

+

64 

+

65# Other package modules 

+

66from .whiteutils import * 

+

67 

+

68class CogError(Exception): 

+

69 """ Any exception raised by Cog. 

+

70 """ 

+

71 def __init__(self, msg, file='', line=0): 

+

72 if file: 

+

73 Exception.__init__(self, "%s(%d): %s" % (file, line, msg)) 

+

74 else: 

+

75 Exception.__init__(self, msg) 

+

76 

+

77class CogUsageError(CogError): 

+

78 """ An error in usage of command-line arguments in cog. 

+

79 """ 

+

80 pass 

+

81 

+

82class CogInternalError(CogError): 

+

83 """ An error in the coding of Cog. Should never happen. 

+

84 """ 

+

85 pass 

+

86 

+

87class CogGeneratedError(CogError): 

+

88 """ An error raised by a user's cog generator. 

+

89 """ 

+

90 pass 

+

91 

+

92class CogUserException(CogError): 

+

93 """ An exception caught when running a user's cog generator. 

+

94 The argument is the traceback message to print. 

+

95 """ 

+

96 pass 

+

97 

+

98class Redirectable: 

+

99 """ An object with its own stdout and stderr files. 

+

100 """ 

+

101 def __init__(self): 

+

102 self.stdout = sys.stdout 

+

103 self.stderr = sys.stderr 

+

104 

+

105 def setOutput(self, stdout=None, stderr=None): 

+

106 """ Assign new files for standard out and/or standard error. 

+

107 """ 

+

108 if stdout: 108 ↛ 110line 108 didn't jump to line 110, because the condition on line 108 was never false

+

109 self.stdout = stdout 

+

110 if stderr: 110 ↛ 111line 110 didn't jump to line 111, because the condition on line 110 was never true

+

111 self.stderr = stderr 

+

112 

+

113 def prout(self, s, end="\n"): 

+

114 print(s, file=self.stdout, end=end) 

+

115 

+

116 def prerr(self, s, end="\n"): 

+

117 print(s, file=self.stderr, end=end) 

118 

-

119class CogGenerator(Redirectable): 

-

120 """ A generator pulled from a source file. 

-

121 """ 

-

122 def __init__(self, options=None): 

-

123 Redirectable.__init__(self) 

-

124 self.markers = [] 

-

125 self.lines = [] 

-

126 self.options = options or CogOptions() 

-

127 

-

128 def parseMarker(self, l): 

-

129 self.markers.append(l) 

-

130 

-

131 def parseLine(self, l): 

-

132 self.lines.append(l.strip('\n')) 

-

133 

-

134 def getCode(self): 

-

135 """ Extract the executable Python code from the generator. 

-

136 """ 

-

137 # If the markers and lines all have the same prefix 

-

138 # (end-of-line comment chars, for example), 

-

139 # then remove it from all the lines. 

-

140 prefIn = commonPrefix(self.markers + self.lines) 

-

141 if prefIn: 

-

142 self.markers = [ l.replace(prefIn, '', 1) for l in self.markers ] 

-

143 self.lines = [ l.replace(prefIn, '', 1) for l in self.lines ] 

-

144 

-

145 return reindentBlock(self.lines, '') 

-

146 

-

147 def evaluate(self, cog, globals, fname): 

-

148 # figure out the right whitespace prefix for the output 

-

149 prefOut = whitePrefix(self.markers) 

-

150 

-

151 intext = self.getCode() 

-

152 if not intext: 

-

153 return '' 

-

154 

-

155 prologue = "import " + cog.cogmodulename + " as cog\n" 

-

156 if self.options.sPrologue: 156 ↛ 157line 156 didn't jump to line 157, because the condition on line 156 was never true

-

157 prologue += self.options.sPrologue + '\n' 

-

158 code = compile(prologue + intext, str(fname), 'exec') 

-

159 

-

160 # Make sure the "cog" module has our state. 

-

161 cog.cogmodule.msg = self.msg 

-

162 cog.cogmodule.out = self.out 

-

163 cog.cogmodule.outl = self.outl 

-

164 cog.cogmodule.error = self.error 

-

165 

-

166 self.outstring = '' 

-

167 try: 

-

168 eval(code, globals) 

-

169 except CogError: 169 ↛ 170line 169 didn't jump to line 170, because the exception caught by line 169 didn't happen

-

170 raise 

-

171 except: 

-

172 typ, err, tb = sys.exc_info() 

-

173 frames = (tuple(fr) for fr in traceback.extract_tb(tb.tb_next)) 

-

174 frames = find_cog_source(frames, prologue) 

-

175 msg = "".join(traceback.format_list(frames)) 

-

176 msg += "{}: {}".format(typ.__name__, err) 

-

177 raise CogUserException(msg) 

-

178 

-

179 # We need to make sure that the last line in the output 

-

180 # ends with a newline, or it will be joined to the 

-

181 # end-output line, ruining cog's idempotency. 

-

182 if self.outstring and self.outstring[-1] != '\n': 

-

183 self.outstring += '\n' 

-

184 

-

185 return reindentBlock(self.outstring, prefOut) 

-

186 

-

187 def msg(self, s): 

-

188 self.prout("Message: "+s) 

-

189 

-

190 def out(self, sOut='', dedent=False, trimblanklines=False): 

-

191 """ The cog.out function. 

-

192 """ 

-

193 if trimblanklines and ('\n' in sOut): 

-

194 lines = sOut.split('\n') 

-

195 if lines[0].strip() == '': 

-

196 del lines[0] 

-

197 if lines and lines[-1].strip() == '': 

-

198 del lines[-1] 

-

199 sOut = '\n'.join(lines)+'\n' 

-

200 if dedent: 

-

201 sOut = reindentBlock(sOut) 

-

202 self.outstring += sOut 

-

203 

-

204 def outl(self, sOut='', **kw): 

-

205 """ The cog.outl function. 

-

206 """ 

-

207 self.out(sOut, **kw) 

-

208 self.out('\n') 

-

209 

-

210 def error(self, msg='Error raised by cog generator.'): 

-

211 """ The cog.error function. 

-

212 Instead of raising standard python errors, cog generators can use 

-

213 this function. It will display the error without a scary Python 

-

214 traceback. 

-

215 """ 

-

216 raise CogGeneratedError(msg) 

-

217 

-

218 

-

219class NumberedFileReader: 

-

220 """ A decorator for files that counts the readline()'s called. 

-

221 """ 

-

222 def __init__(self, f): 

-

223 self.f = f 

-

224 self.n = 0 

-

225 

-

226 def readline(self): 

-

227 l = self.f.readline() 

-

228 if l: 

-

229 self.n += 1 

-

230 return l 

-

231 

-

232 def linenumber(self): 

-

233 return self.n 

-

234 

+

119 

+

120class CogGenerator(Redirectable): 

+

121 """ A generator pulled from a source file. 

+

122 """ 

+

123 def __init__(self, options=None): 

+

124 Redirectable.__init__(self) 

+

125 self.markers = [] 

+

126 self.lines = [] 

+

127 self.options = options or CogOptions() 

+

128 

+

129 def parseMarker(self, l): 

+

130 self.markers.append(l) 

+

131 

+

132 def parseLine(self, l): 

+

133 self.lines.append(l.strip('\n')) 

+

134 

+

135 def getCode(self): 

+

136 """ Extract the executable Python code from the generator. 

+

137 """ 

+

138 # If the markers and lines all have the same prefix 

+

139 # (end-of-line comment chars, for example), 

+

140 # then remove it from all the lines. 

+

141 prefIn = commonPrefix(self.markers + self.lines) 

+

142 if prefIn: 

+

143 self.markers = [ l.replace(prefIn, '', 1) for l in self.markers ] 

+

144 self.lines = [ l.replace(prefIn, '', 1) for l in self.lines ] 

+

145 

+

146 return reindentBlock(self.lines, '') 

+

147 

+

148 def evaluate(self, cog, globals, fname): 

+

149 # figure out the right whitespace prefix for the output 

+

150 prefOut = whitePrefix(self.markers) 

+

151 

+

152 intext = self.getCode() 

+

153 if not intext: 

+

154 return '' 

+

155 

+

156 prologue = "import " + cog.cogmodulename + " as cog\n" 

+

157 if self.options.sPrologue: 157 ↛ 158line 157 didn't jump to line 158, because the condition on line 157 was never true

+

158 prologue += self.options.sPrologue + '\n' 

+

159 code = compile(prologue + intext, str(fname), 'exec') 

+

160 

+

161 # Make sure the "cog" module has our state. 

+

162 cog.cogmodule.msg = self.msg 

+

163 cog.cogmodule.out = self.out 

+

164 cog.cogmodule.outl = self.outl 

+

165 cog.cogmodule.error = self.error 

+

166 

+

167 real_stdout = sys.stdout 

+

168 if self.options.bPrintOutput: 168 ↛ 169line 168 didn't jump to line 169, because the condition on line 168 was never true

+

169 sys.stdout = captured_stdout = StringIO() 

+

170 

+

171 self.outstring = '' 

+

172 try: 

+

173 eval(code, globals) 

+

174 except CogError: 174 ↛ 175line 174 didn't jump to line 175, because the exception caught by line 174 didn't happen

+

175 raise 

+

176 except: 

+

177 typ, err, tb = sys.exc_info() 

+

178 frames = (tuple(fr) for fr in traceback.extract_tb(tb.tb_next)) 

+

179 frames = find_cog_source(frames, prologue) 

+

180 msg = "".join(traceback.format_list(frames)) 

+

181 msg += "{}: {}".format(typ.__name__, err) 

+

182 raise CogUserException(msg) 

+

183 finally: 

+

184 sys.stdout = real_stdout 

+

185 

+

186 if self.options.bPrintOutput: 186 ↛ 187line 186 didn't jump to line 187, because the condition on line 186 was never true

+

187 self.outstring = captured_stdout.getvalue() 

+

188 

+

189 # We need to make sure that the last line in the output 

+

190 # ends with a newline, or it will be joined to the 

+

191 # end-output line, ruining cog's idempotency. 

+

192 if self.outstring and self.outstring[-1] != '\n': 

+

193 self.outstring += '\n' 

+

194 

+

195 return reindentBlock(self.outstring, prefOut) 

+

196 

+

197 def msg(self, s): 

+

198 self.prout("Message: "+s) 

+

199 

+

200 def out(self, sOut='', dedent=False, trimblanklines=False): 

+

201 """ The cog.out function. 

+

202 """ 

+

203 if trimblanklines and ('\n' in sOut): 

+

204 lines = sOut.split('\n') 

+

205 if lines[0].strip() == '': 

+

206 del lines[0] 

+

207 if lines and lines[-1].strip() == '': 

+

208 del lines[-1] 

+

209 sOut = '\n'.join(lines)+'\n' 

+

210 if dedent: 

+

211 sOut = reindentBlock(sOut) 

+

212 self.outstring += sOut 

+

213 

+

214 def outl(self, sOut='', **kw): 

+

215 """ The cog.outl function. 

+

216 """ 

+

217 self.out(sOut, **kw) 

+

218 self.out('\n') 

+

219 

+

220 def error(self, msg='Error raised by cog generator.'): 

+

221 """ The cog.error function. 

+

222 Instead of raising standard python errors, cog generators can use 

+

223 this function. It will display the error without a scary Python 

+

224 traceback. 

+

225 """ 

+

226 raise CogGeneratedError(msg) 

+

227 

+

228 

+

229class NumberedFileReader: 

+

230 """ A decorator for files that counts the readline()'s called. 

+

231 """ 

+

232 def __init__(self, f): 

+

233 self.f = f 

+

234 self.n = 0 

235 

-

236class CogOptions: 

-

237 """ Options for a run of cog. 

-

238 """ 

-

239 def __init__(self): 

-

240 # Defaults for argument values. 

-

241 self.args = [] 

-

242 self.includePath = [] 

-

243 self.defines = {} 

-

244 self.bShowVersion = False 

-

245 self.sMakeWritableCmd = None 

-

246 self.bReplace = False 

-

247 self.bNoGenerate = False 

-

248 self.sOutputName = None 

-

249 self.bWarnEmpty = False 

-

250 self.bHashOutput = False 

-

251 self.bDeleteCode = False 

-

252 self.bEofCanBeEnd = False 

-

253 self.sSuffix = None 

-

254 self.bNewlines = False 

-

255 self.sBeginSpec = '[[[cog' 

-

256 self.sEndSpec = ']]]' 

-

257 self.sEndOutput = '[[[end]]]' 

-

258 self.sEncoding = "utf-8" 

-

259 self.verbosity = 2 

-

260 self.sPrologue = '' 

-

261 

-

262 def __eq__(self, other): 

-

263 """ Comparison operator for tests to use. 

-

264 """ 

-

265 return self.__dict__ == other.__dict__ 

-

266 

-

267 def clone(self): 

-

268 """ Make a clone of these options, for further refinement. 

-

269 """ 

-

270 return copy.deepcopy(self) 

-

271 

-

272 def addToIncludePath(self, dirs): 

-

273 """ Add directories to the include path. 

-

274 """ 

-

275 dirs = dirs.split(os.pathsep) 

-

276 self.includePath.extend(dirs) 

+

236 def readline(self): 

+

237 l = self.f.readline() 

+

238 if l: 

+

239 self.n += 1 

+

240 return l 

+

241 

+

242 def linenumber(self): 

+

243 return self.n 

+

244 

+

245 

+

246class CogOptions: 

+

247 """ Options for a run of cog. 

+

248 """ 

+

249 def __init__(self): 

+

250 # Defaults for argument values. 

+

251 self.args = [] 

+

252 self.includePath = [] 

+

253 self.defines = {} 

+

254 self.bShowVersion = False 

+

255 self.sMakeWritableCmd = None 

+

256 self.bReplace = False 

+

257 self.bNoGenerate = False 

+

258 self.sOutputName = None 

+

259 self.bWarnEmpty = False 

+

260 self.bHashOutput = False 

+

261 self.bDeleteCode = False 

+

262 self.bEofCanBeEnd = False 

+

263 self.sSuffix = None 

+

264 self.bNewlines = False 

+

265 self.sBeginSpec = '[[[cog' 

+

266 self.sEndSpec = ']]]' 

+

267 self.sEndOutput = '[[[end]]]' 

+

268 self.sEncoding = "utf-8" 

+

269 self.verbosity = 2 

+

270 self.sPrologue = '' 

+

271 self.bPrintOutput = False 

+

272 

+

273 def __eq__(self, other): 

+

274 """ Comparison operator for tests to use. 

+

275 """ 

+

276 return self.__dict__ == other.__dict__ 

277 

-

278 def parseArgs(self, argv): 

-

279 # Parse the command line arguments. 

-

280 try: 

-

281 opts, self.args = getopt.getopt( 

-

282 argv, 

-

283 'cdD:eI:n:o:rs:p:Uvw:xz', 

-

284 [ 

-

285 'markers=', 

-

286 'verbosity=', 

-

287 ] 

-

288 ) 

-

289 except getopt.error as msg: 

-

290 raise CogUsageError(msg) 

-

291 

-

292 # Handle the command line arguments. 

-

293 for o, a in opts: 

-

294 if o == '-c': 

-

295 self.bHashOutput = True 

-

296 elif o == '-d': 

-

297 self.bDeleteCode = True 

-

298 elif o == '-D': 

-

299 if a.count('=') < 1: 

-

300 raise CogUsageError("-D takes a name=value argument") 

-

301 name, value = a.split('=', 1) 

-

302 self.defines[name] = value 

-

303 elif o == '-e': 

-

304 self.bWarnEmpty = True 

-

305 elif o == '-I': 

-

306 self.addToIncludePath(os.path.abspath(a)) 

-

307 elif o == '-n': 

-

308 self.sEncoding = a 

-

309 elif o == '-o': 

-

310 self.sOutputName = a 

-

311 elif o == '-r': 

-

312 self.bReplace = True 

-

313 elif o == '-s': 

-

314 self.sSuffix = a 

-

315 elif o == '-p': 

-

316 self.sPrologue = a 

-

317 elif o == '-U': 

-

318 self.bNewlines = True 

-

319 elif o == '-v': 

-

320 self.bShowVersion = True 

-

321 elif o == '-w': 

-

322 self.sMakeWritableCmd = a 

-

323 elif o == '-x': 

-

324 self.bNoGenerate = True 

-

325 elif o == '-z': 

-

326 self.bEofCanBeEnd = True 

-

327 elif o == '--markers': 

-

328 self._parse_markers(a) 

-

329 elif o == '--verbosity': 

-

330 self.verbosity = int(a) 

-

331 else: 

-

332 # Since getopt.getopt is given a list of possible flags, 

-

333 # this is an internal error. 

-

334 raise CogInternalError("Don't understand argument %s" % o) 

-

335 

-

336 def _parse_markers(self, val): 

-

337 try: 

-

338 self.sBeginSpec, self.sEndSpec, self.sEndOutput = val.split(' ') 

-

339 except ValueError: 

-

340 raise CogUsageError( 

-

341 '--markers requires 3 values separated by spaces, could not parse %r' % val 

-

342 ) 

-

343 

-

344 def validate(self): 

-

345 """ Does nothing if everything is OK, raises CogError's if it's not. 

-

346 """ 

-

347 if self.bReplace and self.bDeleteCode: 

-

348 raise CogUsageError("Can't use -d with -r (or you would delete all your source!)") 

-

349 

-

350 if self.bReplace and self.sOutputName: 

-

351 raise CogUsageError("Can't use -o with -r (they are opposites)") 

-

352 

-

353 

-

354class Cog(Redirectable): 

-

355 """ The Cog engine. 

-

356 """ 

-

357 def __init__(self): 

-

358 Redirectable.__init__(self) 

-

359 self.options = CogOptions() 

-

360 self._fixEndOutputPatterns() 

-

361 self.cogmodulename = "cog" 

-

362 self.createCogModule() 

-

363 

-

364 def _fixEndOutputPatterns(self): 

-

365 end_output = re.escape(self.options.sEndOutput) 

-

366 self.reEndOutput = re.compile(end_output + r'(?P<hashsect> *\(checksum: (?P<hash>[a-f0-9]+)\))') 

-

367 self.sEndFormat = self.options.sEndOutput + ' (checksum: %s)' 

-

368 

-

369 def showWarning(self, msg): 

-

370 self.prout("Warning: "+msg) 

-

371 

-

372 def isBeginSpecLine(self, s): 

-

373 return self.options.sBeginSpec in s 

-

374 

-

375 def isEndSpecLine(self, s): 

-

376 return self.options.sEndSpec in s and not self.isEndOutputLine(s) 

-

377 

-

378 def isEndOutputLine(self, s): 

-

379 return self.options.sEndOutput in s 

-

380 

-

381 def createCogModule(self): 

-

382 """ Make a cog "module" object so that imported Python modules 

-

383 can say "import cog" and get our state. 

-

384 """ 

-

385 class DummyModule(object): 

-

386 """Modules don't have to be anything special, just an object will do.""" 

-

387 pass 

-

388 self.cogmodule = DummyModule() 

-

389 self.cogmodule.path = [] 

+

278 def clone(self): 

+

279 """ Make a clone of these options, for further refinement. 

+

280 """ 

+

281 return copy.deepcopy(self) 

+

282 

+

283 def addToIncludePath(self, dirs): 

+

284 """ Add directories to the include path. 

+

285 """ 

+

286 dirs = dirs.split(os.pathsep) 

+

287 self.includePath.extend(dirs) 

+

288 

+

289 def parseArgs(self, argv): 

+

290 # Parse the command line arguments. 

+

291 try: 

+

292 opts, self.args = getopt.getopt( 

+

293 argv, 

+

294 'cdD:eI:n:o:rs:p:PUvw:xz', 

+

295 [ 

+

296 'markers=', 

+

297 'verbosity=', 

+

298 ] 

+

299 ) 

+

300 except getopt.error as msg: 

+

301 raise CogUsageError(msg) 

+

302 

+

303 # Handle the command line arguments. 

+

304 for o, a in opts: 

+

305 if o == '-c': 

+

306 self.bHashOutput = True 

+

307 elif o == '-d': 

+

308 self.bDeleteCode = True 

+

309 elif o == '-D': 

+

310 if a.count('=') < 1: 

+

311 raise CogUsageError("-D takes a name=value argument") 

+

312 name, value = a.split('=', 1) 

+

313 self.defines[name] = value 

+

314 elif o == '-e': 

+

315 self.bWarnEmpty = True 

+

316 elif o == '-I': 

+

317 self.addToIncludePath(os.path.abspath(a)) 

+

318 elif o == '-n': 

+

319 self.sEncoding = a 

+

320 elif o == '-o': 

+

321 self.sOutputName = a 

+

322 elif o == '-r': 

+

323 self.bReplace = True 

+

324 elif o == '-s': 

+

325 self.sSuffix = a 

+

326 elif o == '-p': 

+

327 self.sPrologue = a 

+

328 elif o == '-P': 

+

329 self.bPrintOutput = True 

+

330 elif o == '-U': 

+

331 self.bNewlines = True 

+

332 elif o == '-v': 

+

333 self.bShowVersion = True 

+

334 elif o == '-w': 

+

335 self.sMakeWritableCmd = a 

+

336 elif o == '-x': 

+

337 self.bNoGenerate = True 

+

338 elif o == '-z': 

+

339 self.bEofCanBeEnd = True 

+

340 elif o == '--markers': 

+

341 self._parse_markers(a) 

+

342 elif o == '--verbosity': 

+

343 self.verbosity = int(a) 

+

344 else: 

+

345 # Since getopt.getopt is given a list of possible flags, 

+

346 # this is an internal error. 

+

347 raise CogInternalError("Don't understand argument %s" % o) 

+

348 

+

349 def _parse_markers(self, val): 

+

350 try: 

+

351 self.sBeginSpec, self.sEndSpec, self.sEndOutput = val.split(' ') 

+

352 except ValueError: 

+

353 raise CogUsageError( 

+

354 '--markers requires 3 values separated by spaces, could not parse %r' % val 

+

355 ) 

+

356 

+

357 def validate(self): 

+

358 """ Does nothing if everything is OK, raises CogError's if it's not. 

+

359 """ 

+

360 if self.bReplace and self.bDeleteCode: 

+

361 raise CogUsageError("Can't use -d with -r (or you would delete all your source!)") 

+

362 

+

363 if self.bReplace and self.sOutputName: 

+

364 raise CogUsageError("Can't use -o with -r (they are opposites)") 

+

365 

+

366 

+

367class Cog(Redirectable): 

+

368 """ The Cog engine. 

+

369 """ 

+

370 def __init__(self): 

+

371 Redirectable.__init__(self) 

+

372 self.options = CogOptions() 

+

373 self._fixEndOutputPatterns() 

+

374 self.cogmodulename = "cog" 

+

375 self.createCogModule() 

+

376 

+

377 def _fixEndOutputPatterns(self): 

+

378 end_output = re.escape(self.options.sEndOutput) 

+

379 self.reEndOutput = re.compile(end_output + r'(?P<hashsect> *\(checksum: (?P<hash>[a-f0-9]+)\))') 

+

380 self.sEndFormat = self.options.sEndOutput + ' (checksum: %s)' 

+

381 

+

382 def showWarning(self, msg): 

+

383 self.prout("Warning: "+msg) 

+

384 

+

385 def isBeginSpecLine(self, s): 

+

386 return self.options.sBeginSpec in s 

+

387 

+

388 def isEndSpecLine(self, s): 

+

389 return self.options.sEndSpec in s and not self.isEndOutputLine(s) 

390 

-

391 def openOutputFile(self, fname): 

-

392 """ Open an output file, taking all the details into account. 

-

393 """ 

-

394 opts = {} 

-

395 mode = "w" 

-

396 if PY3: 

-

397 opts['encoding'] = self.options.sEncoding 

-

398 if self.options.bNewlines: 

-

399 if PY3: 

-

400 opts['newline'] = "\n" 

-

401 else: 

-

402 mode = "wb" 

-

403 fdir = os.path.dirname(fname) 

-

404 if os.path.dirname(fdir) and not os.path.exists(fdir): 

-

405 os.makedirs(fdir) 

-

406 return open(fname, mode, **opts) 

-

407 

-

408 def openInputFile(self, fname): 

-

409 """ Open an input file. """ 

-

410 if fname == "-": 

-

411 return sys.stdin 

-

412 else: 

-

413 opts = {} 

-

414 if PY3: 

-

415 opts['encoding'] = self.options.sEncoding 

-

416 return open(fname, "r", **opts) 

-

417 

-

418 def processFile(self, fIn, fOut, fname=None, globals=None): 

-

419 """ Process an input file object to an output file object. 

-

420 fIn and fOut can be file objects, or file names. 

-

421 """ 

-

422 

-

423 sFileIn = fname or '' 

-

424 sFileOut = fname or '' 

-

425 fInToClose = fOutToClose = None 

-

426 # Convert filenames to files. 

-

427 if isinstance(fIn, string_types): 427 ↛ 429line 427 didn't jump to line 429, because the condition on line 427 was never true

-

428 # Open the input file. 

-

429 sFileIn = fIn 

-

430 fIn = fInToClose = self.openInputFile(fIn) 

-

431 if isinstance(fOut, string_types): 431 ↛ 433line 431 didn't jump to line 433, because the condition on line 431 was never true

-

432 # Open the output file. 

-

433 sFileOut = fOut 

-

434 fOut = fOutToClose = self.openOutputFile(fOut) 

+

391 def isEndOutputLine(self, s): 

+

392 return self.options.sEndOutput in s 

+

393 

+

394 def createCogModule(self): 

+

395 """ Make a cog "module" object so that imported Python modules 

+

396 can say "import cog" and get our state. 

+

397 """ 

+

398 class DummyModule(object): 

+

399 """Modules don't have to be anything special, just an object will do.""" 

+

400 pass 

+

401 self.cogmodule = DummyModule() 

+

402 self.cogmodule.path = [] 

+

403 

+

404 def openOutputFile(self, fname): 

+

405 """ Open an output file, taking all the details into account. 

+

406 """ 

+

407 opts = {} 

+

408 mode = "w" 

+

409 if PY3: 

+

410 opts['encoding'] = self.options.sEncoding 

+

411 if self.options.bNewlines: 

+

412 if PY3: 

+

413 opts['newline'] = "\n" 

+

414 else: 

+

415 mode = "wb" 

+

416 fdir = os.path.dirname(fname) 

+

417 if os.path.dirname(fdir) and not os.path.exists(fdir): 

+

418 os.makedirs(fdir) 

+

419 return open(fname, mode, **opts) 

+

420 

+

421 def openInputFile(self, fname): 

+

422 """ Open an input file. """ 

+

423 if fname == "-": 

+

424 return sys.stdin 

+

425 else: 

+

426 opts = {} 

+

427 if PY3: 

+

428 opts['encoding'] = self.options.sEncoding 

+

429 return open(fname, "r", **opts) 

+

430 

+

431 def processFile(self, fIn, fOut, fname=None, globals=None): 

+

432 """ Process an input file object to an output file object. 

+

433 fIn and fOut can be file objects, or file names. 

+

434 """ 

435 

-

436 try: 

-

437 fIn = NumberedFileReader(fIn) 

-

438 

-

439 bSawCog = False 

-

440 

-

441 self.cogmodule.inFile = sFileIn 

-

442 self.cogmodule.outFile = sFileOut 

-

443 self.cogmodulename = 'cog_' + hashlib.md5(sFileOut.encode()).hexdigest() 

-

444 sys.modules[self.cogmodulename] = self.cogmodule 

-

445 # if "import cog" explicitly done in code by user, note threading will cause clashes. 

-

446 sys.modules['cog'] = self.cogmodule 

-

447 

-

448 # The globals dict we'll use for this file. 

-

449 if globals is None: 449 ↛ 453line 449 didn't jump to line 453, because the condition on line 449 was never false

-

450 globals = {} 

+

436 sFileIn = fname or '' 

+

437 sFileOut = fname or '' 

+

438 fInToClose = fOutToClose = None 

+

439 # Convert filenames to files. 

+

440 if isinstance(fIn, string_types): 440 ↛ 442line 440 didn't jump to line 442, because the condition on line 440 was never true

+

441 # Open the input file. 

+

442 sFileIn = fIn 

+

443 fIn = fInToClose = self.openInputFile(fIn) 

+

444 if isinstance(fOut, string_types): 444 ↛ 446line 444 didn't jump to line 446, because the condition on line 444 was never true

+

445 # Open the output file. 

+

446 sFileOut = fOut 

+

447 fOut = fOutToClose = self.openOutputFile(fOut) 

+

448 

+

449 try: 

+

450 fIn = NumberedFileReader(fIn) 

451 

-

452 # If there are any global defines, put them in the globals. 

-

453 globals.update(self.options.defines) 

-

454 

-

455 # loop over generator chunks 

-

456 l = fIn.readline() 

-

457 while l: 

-

458 # Find the next spec begin 

-

459 while l and not self.isBeginSpecLine(l): 

-

460 if self.isEndSpecLine(l): 460 ↛ 461line 460 didn't jump to line 461, because the condition on line 460 was never true

-

461 raise CogError("Unexpected '%s'" % self.options.sEndSpec, 

-

462 file=sFileIn, line=fIn.linenumber()) 

-

463 if self.isEndOutputLine(l): 463 ↛ 464line 463 didn't jump to line 464, because the condition on line 463 was never true

-

464 raise CogError("Unexpected '%s'" % self.options.sEndOutput, 

-

465 file=sFileIn, line=fIn.linenumber()) 

-

466 fOut.write(l) 

-

467 l = fIn.readline() 

-

468 if not l: 

-

469 break 

-

470 if not self.options.bDeleteCode: 470 ↛ 474line 470 didn't jump to line 474, because the condition on line 470 was never false

-

471 fOut.write(l) 

-

472 

-

473 # l is the begin spec 

-

474 gen = CogGenerator(options=self.options) 

-

475 gen.setOutput(stdout=self.stdout) 

-

476 gen.parseMarker(l) 

-

477 firstLineNum = fIn.linenumber() 

-

478 self.cogmodule.firstLineNum = firstLineNum 

-

479 

-

480 # If the spec begin is also a spec end, then process the single 

-

481 # line of code inside. 

-

482 if self.isEndSpecLine(l): 

-

483 beg = l.find(self.options.sBeginSpec) 

-

484 end = l.find(self.options.sEndSpec) 

-

485 if beg > end: 

-

486 raise CogError("Cog code markers inverted", 

-

487 file=sFileIn, line=firstLineNum) 

-

488 else: 

-

489 sCode = l[beg+len(self.options.sBeginSpec):end].strip() 

-

490 gen.parseLine(sCode) 

-

491 else: 

-

492 # Deal with an ordinary code block. 

-

493 l = fIn.readline() 

-

494 

-

495 # Get all the lines in the spec 

-

496 while l and not self.isEndSpecLine(l): 

-

497 if self.isBeginSpecLine(l): 497 ↛ 498line 497 didn't jump to line 498, because the condition on line 497 was never true

-

498 raise CogError("Unexpected '%s'" % self.options.sBeginSpec, 

-

499 file=sFileIn, line=fIn.linenumber()) 

-

500 if self.isEndOutputLine(l): 500 ↛ 501line 500 didn't jump to line 501, because the condition on line 500 was never true

-

501 raise CogError("Unexpected '%s'" % self.options.sEndOutput, 

-

502 file=sFileIn, line=fIn.linenumber()) 

-

503 if not self.options.bDeleteCode: 503 ↛ 505line 503 didn't jump to line 505, because the condition on line 503 was never false

-

504 fOut.write(l) 

-

505 gen.parseLine(l) 

-

506 l = fIn.readline() 

-

507 if not l: 507 ↛ 508line 507 didn't jump to line 508, because the condition on line 507 was never true

-

508 raise CogError( 

-

509 "Cog block begun but never ended.", 

-

510 file=sFileIn, line=firstLineNum) 

-

511 

-

512 if not self.options.bDeleteCode: 512 ↛ 514line 512 didn't jump to line 514, because the condition on line 512 was never false

-

513 fOut.write(l) 

-

514 gen.parseMarker(l) 

-

515 

-

516 l = fIn.readline() 

-

517 

-

518 # Eat all the lines in the output section. While reading past 

-

519 # them, compute the md5 hash of the old output. 

-

520 previous = "" 

-

521 hasher = hashlib.md5() 

-

522 while l and not self.isEndOutputLine(l): 

-

523 if self.isBeginSpecLine(l): 523 ↛ 524line 523 didn't jump to line 524, because the condition on line 523 was never true

-

524 raise CogError("Unexpected '%s'" % self.options.sBeginSpec, 

-

525 file=sFileIn, line=fIn.linenumber()) 

-

526 if self.isEndSpecLine(l): 526 ↛ 527line 526 didn't jump to line 527, because the condition on line 526 was never true

-

527 raise CogError("Unexpected '%s'" % self.options.sEndSpec, 

-

528 file=sFileIn, line=fIn.linenumber()) 

-

529 previous += l 

-

530 hasher.update(to_bytes(l)) 

-

531 l = fIn.readline() 

-

532 curHash = hasher.hexdigest() 

-

533 

-

534 if not l and not self.options.bEofCanBeEnd: 534 ↛ 536line 534 didn't jump to line 536, because the condition on line 534 was never true

-

535 # We reached end of file before we found the end output line. 

-

536 raise CogError("Missing '%s' before end of file." % self.options.sEndOutput, 

-

537 file=sFileIn, line=fIn.linenumber()) 

-

538 

-

539 # Make the previous output available to the current code 

-

540 self.cogmodule.previous = previous 

-

541 

-

542 # Write the output of the spec to be the new output if we're 

-

543 # supposed to generate code. 

-

544 hasher = hashlib.md5() 

-

545 if not self.options.bNoGenerate: 545 ↛ 551line 545 didn't jump to line 551, because the condition on line 545 was never false

-

546 sFile = "<cog %s:%d>" % (sFileIn, firstLineNum) 

-

547 sGen = gen.evaluate(cog=self, globals=globals, fname=sFile) 

-

548 sGen = self.suffixLines(sGen) 

-

549 hasher.update(to_bytes(sGen)) 

-

550 fOut.write(sGen) 

-

551 newHash = hasher.hexdigest() 

-

552 

-

553 bSawCog = True 

+

452 bSawCog = False 

+

453 

+

454 self.cogmodule.inFile = sFileIn 

+

455 self.cogmodule.outFile = sFileOut 

+

456 self.cogmodulename = 'cog_' + hashlib.md5(sFileOut.encode()).hexdigest() 

+

457 sys.modules[self.cogmodulename] = self.cogmodule 

+

458 # if "import cog" explicitly done in code by user, note threading will cause clashes. 

+

459 sys.modules['cog'] = self.cogmodule 

+

460 

+

461 # The globals dict we'll use for this file. 

+

462 if globals is None: 462 ↛ 466line 462 didn't jump to line 466, because the condition on line 462 was never false

+

463 globals = {} 

+

464 

+

465 # If there are any global defines, put them in the globals. 

+

466 globals.update(self.options.defines) 

+

467 

+

468 # loop over generator chunks 

+

469 l = fIn.readline() 

+

470 while l: 

+

471 # Find the next spec begin 

+

472 while l and not self.isBeginSpecLine(l): 

+

473 if self.isEndSpecLine(l): 473 ↛ 474line 473 didn't jump to line 474, because the condition on line 473 was never true

+

474 raise CogError("Unexpected '%s'" % self.options.sEndSpec, 

+

475 file=sFileIn, line=fIn.linenumber()) 

+

476 if self.isEndOutputLine(l): 476 ↛ 477line 476 didn't jump to line 477, because the condition on line 476 was never true

+

477 raise CogError("Unexpected '%s'" % self.options.sEndOutput, 

+

478 file=sFileIn, line=fIn.linenumber()) 

+

479 fOut.write(l) 

+

480 l = fIn.readline() 

+

481 if not l: 

+

482 break 

+

483 if not self.options.bDeleteCode: 483 ↛ 487line 483 didn't jump to line 487, because the condition on line 483 was never false

+

484 fOut.write(l) 

+

485 

+

486 # l is the begin spec 

+

487 gen = CogGenerator(options=self.options) 

+

488 gen.setOutput(stdout=self.stdout) 

+

489 gen.parseMarker(l) 

+

490 firstLineNum = fIn.linenumber() 

+

491 self.cogmodule.firstLineNum = firstLineNum 

+

492 

+

493 # If the spec begin is also a spec end, then process the single 

+

494 # line of code inside. 

+

495 if self.isEndSpecLine(l): 

+

496 beg = l.find(self.options.sBeginSpec) 

+

497 end = l.find(self.options.sEndSpec) 

+

498 if beg > end: 

+

499 raise CogError("Cog code markers inverted", 

+

500 file=sFileIn, line=firstLineNum) 

+

501 else: 

+

502 sCode = l[beg+len(self.options.sBeginSpec):end].strip() 

+

503 gen.parseLine(sCode) 

+

504 else: 

+

505 # Deal with an ordinary code block. 

+

506 l = fIn.readline() 

+

507 

+

508 # Get all the lines in the spec 

+

509 while l and not self.isEndSpecLine(l): 

+

510 if self.isBeginSpecLine(l): 510 ↛ 511line 510 didn't jump to line 511, because the condition on line 510 was never true

+

511 raise CogError("Unexpected '%s'" % self.options.sBeginSpec, 

+

512 file=sFileIn, line=fIn.linenumber()) 

+

513 if self.isEndOutputLine(l): 513 ↛ 514line 513 didn't jump to line 514, because the condition on line 513 was never true

+

514 raise CogError("Unexpected '%s'" % self.options.sEndOutput, 

+

515 file=sFileIn, line=fIn.linenumber()) 

+

516 if not self.options.bDeleteCode: 516 ↛ 518line 516 didn't jump to line 518, because the condition on line 516 was never false

+

517 fOut.write(l) 

+

518 gen.parseLine(l) 

+

519 l = fIn.readline() 

+

520 if not l: 520 ↛ 521line 520 didn't jump to line 521, because the condition on line 520 was never true

+

521 raise CogError( 

+

522 "Cog block begun but never ended.", 

+

523 file=sFileIn, line=firstLineNum) 

+

524 

+

525 if not self.options.bDeleteCode: 525 ↛ 527line 525 didn't jump to line 527, because the condition on line 525 was never false

+

526 fOut.write(l) 

+

527 gen.parseMarker(l) 

+

528 

+

529 l = fIn.readline() 

+

530 

+

531 # Eat all the lines in the output section. While reading past 

+

532 # them, compute the md5 hash of the old output. 

+

533 previous = "" 

+

534 hasher = hashlib.md5() 

+

535 while l and not self.isEndOutputLine(l): 

+

536 if self.isBeginSpecLine(l): 536 ↛ 537line 536 didn't jump to line 537, because the condition on line 536 was never true

+

537 raise CogError("Unexpected '%s'" % self.options.sBeginSpec, 

+

538 file=sFileIn, line=fIn.linenumber()) 

+

539 if self.isEndSpecLine(l): 539 ↛ 540line 539 didn't jump to line 540, because the condition on line 539 was never true

+

540 raise CogError("Unexpected '%s'" % self.options.sEndSpec, 

+

541 file=sFileIn, line=fIn.linenumber()) 

+

542 previous += l 

+

543 hasher.update(to_bytes(l)) 

+

544 l = fIn.readline() 

+

545 curHash = hasher.hexdigest() 

+

546 

+

547 if not l and not self.options.bEofCanBeEnd: 547 ↛ 549line 547 didn't jump to line 549, because the condition on line 547 was never true

+

548 # We reached end of file before we found the end output line. 

+

549 raise CogError("Missing '%s' before end of file." % self.options.sEndOutput, 

+

550 file=sFileIn, line=fIn.linenumber()) 

+

551 

+

552 # Make the previous output available to the current code 

+

553 self.cogmodule.previous = previous 

554 

-

555 # Write the ending output line 

-

556 hashMatch = self.reEndOutput.search(l) 

-

557 if self.options.bHashOutput: 557 ↛ 558line 557 didn't jump to line 558, because the condition on line 557 was never true

-

558 if hashMatch: 

-

559 oldHash = hashMatch.groupdict()['hash'] 

-

560 if oldHash != curHash: 

-

561 raise CogError("Output has been edited! Delete old checksum to unprotect.", 

-

562 file=sFileIn, line=fIn.linenumber()) 

-

563 # Create a new end line with the correct hash. 

-

564 endpieces = l.split(hashMatch.group(0), 1) 

-

565 else: 

-

566 # There was no old hash, but we want a new hash. 

-

567 endpieces = l.split(self.options.sEndOutput, 1) 

-

568 l = (self.sEndFormat % newHash).join(endpieces) 

-

569 else: 

-

570 # We don't want hashes output, so if there was one, get rid of 

-

571 # it. 

-

572 if hashMatch: 572 ↛ 573line 572 didn't jump to line 573, because the condition on line 572 was never true

-

573 l = l.replace(hashMatch.groupdict()['hashsect'], '', 1) 

-

574 

-

575 if not self.options.bDeleteCode: 575 ↛ 577line 575 didn't jump to line 577, because the condition on line 575 was never false

-

576 fOut.write(l) 

-

577 l = fIn.readline() 

-

578 

-

579 if not bSawCog and self.options.bWarnEmpty: 579 ↛ 580line 579 didn't jump to line 580, because the condition on line 579 was never true

-

580 self.showWarning("no cog code found in %s" % sFileIn) 

-

581 finally: 

-

582 if fInToClose: 582 ↛ 583line 582 didn't jump to line 583, because the condition on line 582 was never true

-

583 fInToClose.close() 

-

584 if fOutToClose: 584 ↛ 585line 584 didn't jump to line 585, because the condition on line 584 was never true

-

585 fOutToClose.close() 

-

586 

+

555 # Write the output of the spec to be the new output if we're 

+

556 # supposed to generate code. 

+

557 hasher = hashlib.md5() 

+

558 if not self.options.bNoGenerate: 558 ↛ 564line 558 didn't jump to line 564, because the condition on line 558 was never false

+

559 sFile = "<cog %s:%d>" % (sFileIn, firstLineNum) 

+

560 sGen = gen.evaluate(cog=self, globals=globals, fname=sFile) 

+

561 sGen = self.suffixLines(sGen) 

+

562 hasher.update(to_bytes(sGen)) 

+

563 fOut.write(sGen) 

+

564 newHash = hasher.hexdigest() 

+

565 

+

566 bSawCog = True 

+

567 

+

568 # Write the ending output line 

+

569 hashMatch = self.reEndOutput.search(l) 

+

570 if self.options.bHashOutput: 570 ↛ 571line 570 didn't jump to line 571, because the condition on line 570 was never true

+

571 if hashMatch: 

+

572 oldHash = hashMatch.groupdict()['hash'] 

+

573 if oldHash != curHash: 

+

574 raise CogError("Output has been edited! Delete old checksum to unprotect.", 

+

575 file=sFileIn, line=fIn.linenumber()) 

+

576 # Create a new end line with the correct hash. 

+

577 endpieces = l.split(hashMatch.group(0), 1) 

+

578 else: 

+

579 # There was no old hash, but we want a new hash. 

+

580 endpieces = l.split(self.options.sEndOutput, 1) 

+

581 l = (self.sEndFormat % newHash).join(endpieces) 

+

582 else: 

+

583 # We don't want hashes output, so if there was one, get rid of 

+

584 # it. 

+

585 if hashMatch: 585 ↛ 586line 585 didn't jump to line 586, because the condition on line 585 was never true

+

586 l = l.replace(hashMatch.groupdict()['hashsect'], '', 1) 

587 

-

588 # A regex for non-empty lines, used by suffixLines. 

-

589 reNonEmptyLines = re.compile(r"^\s*\S+.*$", re.MULTILINE) 

-

590 

-

591 def suffixLines(self, text): 

-

592 """ Add suffixes to the lines in text, if our options desire it. 

-

593 text is many lines, as a single string. 

-

594 """ 

-

595 if self.options.sSuffix: 595 ↛ 597line 595 didn't jump to line 597, because the condition on line 595 was never true

-

596 # Find all non-blank lines, and add the suffix to the end. 

-

597 repl = r"\g<0>" + self.options.sSuffix.replace('\\', '\\\\') 

-

598 text = self.reNonEmptyLines.sub(repl, text) 

-

599 return text 

+

588 if not self.options.bDeleteCode: 588 ↛ 590line 588 didn't jump to line 590, because the condition on line 588 was never false

+

589 fOut.write(l) 

+

590 l = fIn.readline() 

+

591 

+

592 if not bSawCog and self.options.bWarnEmpty: 592 ↛ 593line 592 didn't jump to line 593, because the condition on line 592 was never true

+

593 self.showWarning("no cog code found in %s" % sFileIn) 

+

594 finally: 

+

595 if fInToClose: 595 ↛ 596line 595 didn't jump to line 596, because the condition on line 595 was never true

+

596 fInToClose.close() 

+

597 if fOutToClose: 597 ↛ 598line 597 didn't jump to line 598, because the condition on line 597 was never true

+

598 fOutToClose.close() 

+

599 

600 

-

601 def processString(self, sInput, fname=None): 

-

602 """ Process sInput as the text to cog. 

-

603 Return the cogged output as a string. 

-

604 """ 

-

605 fOld = StringIO(sInput) 

-

606 fNew = StringIO() 

-

607 self.processFile(fOld, fNew, fname=fname) 

-

608 return fNew.getvalue() 

-

609 

-

610 def replaceFile(self, sOldPath, sNewText): 

-

611 """ Replace file sOldPath with the contents sNewText 

-

612 """ 

-

613 if not os.access(sOldPath, os.W_OK): 

-

614 # Need to ensure we can write. 

-

615 if self.options.sMakeWritableCmd: 

-

616 # Use an external command to make the file writable. 

-

617 cmd = self.options.sMakeWritableCmd.replace('%s', sOldPath) 

-

618 self.stdout.write(os.popen(cmd).read()) 

-

619 if not os.access(sOldPath, os.W_OK): 

-

620 raise CogError("Couldn't make %s writable" % sOldPath) 

-

621 else: 

-

622 # Can't write! 

-

623 raise CogError("Can't overwrite %s" % sOldPath) 

-

624 f = self.openOutputFile(sOldPath) 

-

625 f.write(sNewText) 

-

626 f.close() 

-

627 

-

628 def saveIncludePath(self): 

-

629 self.savedInclude = self.options.includePath[:] 

-

630 self.savedSysPath = sys.path[:] 

-

631 

-

632 def restoreIncludePath(self): 

-

633 self.options.includePath = self.savedInclude 

-

634 self.cogmodule.path = self.options.includePath 

-

635 sys.path = self.savedSysPath 

-

636 

-

637 def addToIncludePath(self, includePath): 

-

638 self.cogmodule.path.extend(includePath) 

-

639 sys.path.extend(includePath) 

+

601 # A regex for non-empty lines, used by suffixLines. 

+

602 reNonEmptyLines = re.compile(r"^\s*\S+.*$", re.MULTILINE) 

+

603 

+

604 def suffixLines(self, text): 

+

605 """ Add suffixes to the lines in text, if our options desire it. 

+

606 text is many lines, as a single string. 

+

607 """ 

+

608 if self.options.sSuffix: 608 ↛ 610line 608 didn't jump to line 610, because the condition on line 608 was never true

+

609 # Find all non-blank lines, and add the suffix to the end. 

+

610 repl = r"\g<0>" + self.options.sSuffix.replace('\\', '\\\\') 

+

611 text = self.reNonEmptyLines.sub(repl, text) 

+

612 return text 

+

613 

+

614 def processString(self, sInput, fname=None): 

+

615 """ Process sInput as the text to cog. 

+

616 Return the cogged output as a string. 

+

617 """ 

+

618 fOld = StringIO(sInput) 

+

619 fNew = StringIO() 

+

620 self.processFile(fOld, fNew, fname=fname) 

+

621 return fNew.getvalue() 

+

622 

+

623 def replaceFile(self, sOldPath, sNewText): 

+

624 """ Replace file sOldPath with the contents sNewText 

+

625 """ 

+

626 if not os.access(sOldPath, os.W_OK): 

+

627 # Need to ensure we can write. 

+

628 if self.options.sMakeWritableCmd: 

+

629 # Use an external command to make the file writable. 

+

630 cmd = self.options.sMakeWritableCmd.replace('%s', sOldPath) 

+

631 self.stdout.write(os.popen(cmd).read()) 

+

632 if not os.access(sOldPath, os.W_OK): 

+

633 raise CogError("Couldn't make %s writable" % sOldPath) 

+

634 else: 

+

635 # Can't write! 

+

636 raise CogError("Can't overwrite %s" % sOldPath) 

+

637 f = self.openOutputFile(sOldPath) 

+

638 f.write(sNewText) 

+

639 f.close() 

640 

-

641 def processOneFile(self, sFile): 

-

642 """ Process one filename through cog. 

-

643 """ 

+

641 def saveIncludePath(self): 

+

642 self.savedInclude = self.options.includePath[:] 

+

643 self.savedSysPath = sys.path[:] 

644 

-

645 self.saveIncludePath() 

-

646 bNeedNewline = False 

-

647 

-

648 try: 

-

649 self.addToIncludePath(self.options.includePath) 

-

650 # Since we know where the input file came from, 

-

651 # push its directory onto the include path. 

-

652 self.addToIncludePath([os.path.dirname(sFile)]) 

+

645 def restoreIncludePath(self): 

+

646 self.options.includePath = self.savedInclude 

+

647 self.cogmodule.path = self.options.includePath 

+

648 sys.path = self.savedSysPath 

+

649 

+

650 def addToIncludePath(self, includePath): 

+

651 self.cogmodule.path.extend(includePath) 

+

652 sys.path.extend(includePath) 

653 

-

654 # How we process the file depends on where the output is going. 

-

655 if self.options.sOutputName: 

-

656 self.processFile(sFile, self.options.sOutputName, sFile) 

-

657 elif self.options.bReplace: 

-

658 # We want to replace the cog file with the output, 

-

659 # but only if they differ. 

-

660 if self.options.verbosity >= 2: 

-

661 self.prout("Cogging %s" % sFile, end="") 

-

662 bNeedNewline = True 

-

663 

-

664 try: 

-

665 fOldFile = self.openInputFile(sFile) 

-

666 sOldText = fOldFile.read() 

-

667 fOldFile.close() 

-

668 sNewText = self.processString(sOldText, fname=sFile) 

-

669 if sOldText != sNewText: 

-

670 if self.options.verbosity >= 1: 

-

671 if self.options.verbosity < 2: 

-

672 self.prout("Cogging %s" % sFile, end="") 

-

673 self.prout(" (changed)") 

-

674 bNeedNewline = False 

-

675 self.replaceFile(sFile, sNewText) 

-

676 finally: 

-

677 # The try-finally block is so we can print a partial line 

-

678 # with the name of the file, and print (changed) on the 

-

679 # same line, but also make sure to break the line before 

-

680 # any traceback. 

-

681 if bNeedNewline: 

-

682 self.prout("") 

-

683 else: 

-

684 self.processFile(sFile, self.stdout, sFile) 

-

685 finally: 

-

686 self.restoreIncludePath() 

-

687 

-

688 def processWildcards(self, sFile): 

-

689 files = glob.glob(sFile) 

-

690 if files: 

-

691 for sMatchingFile in files: 

-

692 self.processOneFile(sMatchingFile) 

-

693 else: 

-

694 self.processOneFile(sFile) 

-

695 

-

696 def processFileList(self, sFileList): 

-

697 """ Process the files in a file list. 

-

698 """ 

-

699 flist = self.openInputFile(sFileList) 

-

700 lines = flist.readlines() 

-

701 flist.close() 

-

702 for l in lines: 

-

703 # Use shlex to parse the line like a shell. 

-

704 lex = shlex.shlex(l, posix=True) 

-

705 lex.whitespace_split = True 

-

706 lex.commenters = '#' 

-

707 # No escapes, so that backslash can be part of the path 

-

708 lex.escape = '' 

-

709 args = list(lex) 

-

710 if args: 

-

711 self.processArguments(args) 

-

712 

-

713 def processArguments(self, args): 

-

714 """ Process one command-line. 

-

715 """ 

-

716 saved_options = self.options 

-

717 self.options = self.options.clone() 

-

718 

-

719 self.options.parseArgs(args[1:]) 

-

720 self.options.validate() 

-

721 

-

722 if args[0][0] == '@': 

-

723 if self.options.sOutputName: 

-

724 raise CogUsageError("Can't use -o with @file") 

-

725 self.processFileList(args[0][1:]) 

-

726 else: 

-

727 self.processWildcards(args[0]) 

-

728 

-

729 self.options = saved_options 

-

730 

-

731 def callableMain(self, argv): 

-

732 """ All of command-line cog, but in a callable form. 

-

733 This is used by main. 

-

734 argv is the equivalent of sys.argv. 

-

735 """ 

-

736 argv = argv[1:] 

-

737 

-

738 # Provide help if asked for anywhere in the command line. 

-

739 if '-?' in argv or '-h' in argv: 

-

740 self.prerr(usage, end="") 

-

741 return 

-

742 

-

743 self.options.parseArgs(argv) 

-

744 self.options.validate() 

-

745 self._fixEndOutputPatterns() 

-

746 

-

747 if self.options.bShowVersion: 

-

748 self.prout("Cog version %s" % __version__) 

-

749 return 

+

654 def processOneFile(self, sFile): 

+

655 """ Process one filename through cog. 

+

656 """ 

+

657 

+

658 self.saveIncludePath() 

+

659 bNeedNewline = False 

+

660 

+

661 try: 

+

662 self.addToIncludePath(self.options.includePath) 

+

663 # Since we know where the input file came from, 

+

664 # push its directory onto the include path. 

+

665 self.addToIncludePath([os.path.dirname(sFile)]) 

+

666 

+

667 # How we process the file depends on where the output is going. 

+

668 if self.options.sOutputName: 

+

669 self.processFile(sFile, self.options.sOutputName, sFile) 

+

670 elif self.options.bReplace: 

+

671 # We want to replace the cog file with the output, 

+

672 # but only if they differ. 

+

673 if self.options.verbosity >= 2: 

+

674 self.prout("Cogging %s" % sFile, end="") 

+

675 bNeedNewline = True 

+

676 

+

677 try: 

+

678 fOldFile = self.openInputFile(sFile) 

+

679 sOldText = fOldFile.read() 

+

680 fOldFile.close() 

+

681 sNewText = self.processString(sOldText, fname=sFile) 

+

682 if sOldText != sNewText: 

+

683 if self.options.verbosity >= 1: 

+

684 if self.options.verbosity < 2: 

+

685 self.prout("Cogging %s" % sFile, end="") 

+

686 self.prout(" (changed)") 

+

687 bNeedNewline = False 

+

688 self.replaceFile(sFile, sNewText) 

+

689 finally: 

+

690 # The try-finally block is so we can print a partial line 

+

691 # with the name of the file, and print (changed) on the 

+

692 # same line, but also make sure to break the line before 

+

693 # any traceback. 

+

694 if bNeedNewline: 

+

695 self.prout("") 

+

696 else: 

+

697 self.processFile(sFile, self.stdout, sFile) 

+

698 finally: 

+

699 self.restoreIncludePath() 

+

700 

+

701 def processWildcards(self, sFile): 

+

702 files = glob.glob(sFile) 

+

703 if files: 

+

704 for sMatchingFile in files: 

+

705 self.processOneFile(sMatchingFile) 

+

706 else: 

+

707 self.processOneFile(sFile) 

+

708 

+

709 def processFileList(self, sFileList): 

+

710 """ Process the files in a file list. 

+

711 """ 

+

712 flist = self.openInputFile(sFileList) 

+

713 lines = flist.readlines() 

+

714 flist.close() 

+

715 for l in lines: 

+

716 # Use shlex to parse the line like a shell. 

+

717 lex = shlex.shlex(l, posix=True) 

+

718 lex.whitespace_split = True 

+

719 lex.commenters = '#' 

+

720 # No escapes, so that backslash can be part of the path 

+

721 lex.escape = '' 

+

722 args = list(lex) 

+

723 if args: 

+

724 self.processArguments(args) 

+

725 

+

726 def processArguments(self, args): 

+

727 """ Process one command-line. 

+

728 """ 

+

729 saved_options = self.options 

+

730 self.options = self.options.clone() 

+

731 

+

732 self.options.parseArgs(args[1:]) 

+

733 self.options.validate() 

+

734 

+

735 if args[0][0] == '@': 

+

736 if self.options.sOutputName: 

+

737 raise CogUsageError("Can't use -o with @file") 

+

738 self.processFileList(args[0][1:]) 

+

739 else: 

+

740 self.processWildcards(args[0]) 

+

741 

+

742 self.options = saved_options 

+

743 

+

744 def callableMain(self, argv): 

+

745 """ All of command-line cog, but in a callable form. 

+

746 This is used by main. 

+

747 argv is the equivalent of sys.argv. 

+

748 """ 

+

749 argv = argv[1:] 

750 

-

751 if self.options.args: 

-

752 for a in self.options.args: 

-

753 self.processArguments([a]) 

-

754 else: 

-

755 raise CogUsageError("No files to process") 

-

756 

-

757 def main(self, argv): 

-

758 """ Handle the command-line execution for cog. 

-

759 """ 

-

760 

-

761 try: 

-

762 self.callableMain(argv) 

-

763 return 0 

-

764 except CogUsageError as err: 

-

765 self.prerr(err) 

-

766 self.prerr("(for help use -?)") 

-

767 return 2 

-

768 except CogGeneratedError as err: 

-

769 self.prerr("Error: %s" % err) 

-

770 return 3 

-

771 except CogUserException as err: 

-

772 self.prerr("Traceback (most recent call last):") 

-

773 self.prerr(err.args[0]) 

-

774 return 4 

-

775 except CogError as err: 

-

776 self.prerr(err) 

-

777 return 1 

-

778 

-

779 

-

780def find_cog_source(frame_summary, prologue): 

-

781 """Find cog source lines in a frame summary list, for printing tracebacks. 

-

782 

-

783 Arguments: 

-

784 frame_summary: a list of 4-item tuples, as returned by traceback.extract_tb. 

-

785 prologue: the text of the code prologue. 

-

786 

-

787 Returns 

-

788 A list of 4-item tuples, updated to correct the cog entries. 

-

789 

-

790 """ 

-

791 prolines = prologue.splitlines() 

-

792 for filename, lineno, funcname, source in frame_summary: 

-

793 if not source: 793 ↛ 805line 793 didn't jump to line 805, because the condition on line 793 was never false

-

794 m = re.search(r"^<cog ([^:]+):(\d+)>$", filename) 

-

795 if m: 795 ↛ 796line 795 didn't jump to line 796, because the condition on line 795 was never true

-

796 if lineno <= len(prolines): 

-

797 filename = '<prologue>' 

-

798 source = prolines[lineno-1] 

-

799 lineno -= 1 # Because "import cog" is the first line in the prologue 

-

800 else: 

-

801 filename, coglineno = m.groups() 

-

802 coglineno = int(coglineno) 

-

803 lineno += coglineno - len(prolines) 

-

804 source = linecache.getline(filename, lineno).strip() 

-

805 yield filename, lineno, funcname, source 

-

806 

-

807 

-

808def main(): 

-

809 """Main function for entry_points to use.""" 

-

810 return Cog().main(sys.argv) 

+

751 # Provide help if asked for anywhere in the command line. 

+

752 if '-?' in argv or '-h' in argv: 

+

753 self.prerr(usage, end="") 

+

754 return 

+

755 

+

756 self.options.parseArgs(argv) 

+

757 self.options.validate() 

+

758 self._fixEndOutputPatterns() 

+

759 

+

760 if self.options.bShowVersion: 

+

761 self.prout("Cog version %s" % __version__) 

+

762 return 

+

763 

+

764 if self.options.args: 

+

765 for a in self.options.args: 

+

766 self.processArguments([a]) 

+

767 else: 

+

768 raise CogUsageError("No files to process") 

+

769 

+

770 def main(self, argv): 

+

771 """ Handle the command-line execution for cog. 

+

772 """ 

+

773 

+

774 try: 

+

775 self.callableMain(argv) 

+

776 return 0 

+

777 except CogUsageError as err: 

+

778 self.prerr(err) 

+

779 self.prerr("(for help use -?)") 

+

780 return 2 

+

781 except CogGeneratedError as err: 

+

782 self.prerr("Error: %s" % err) 

+

783 return 3 

+

784 except CogUserException as err: 

+

785 self.prerr("Traceback (most recent call last):") 

+

786 self.prerr(err.args[0]) 

+

787 return 4 

+

788 except CogError as err: 

+

789 self.prerr(err) 

+

790 return 1 

+

791 

+

792 

+

793def find_cog_source(frame_summary, prologue): 

+

794 """Find cog source lines in a frame summary list, for printing tracebacks. 

+

795 

+

796 Arguments: 

+

797 frame_summary: a list of 4-item tuples, as returned by traceback.extract_tb. 

+

798 prologue: the text of the code prologue. 

+

799 

+

800 Returns 

+

801 A list of 4-item tuples, updated to correct the cog entries. 

+

802 

+

803 """ 

+

804 prolines = prologue.splitlines() 

+

805 for filename, lineno, funcname, source in frame_summary: 

+

806 if not source: 806 ↛ 818line 806 didn't jump to line 818, because the condition on line 806 was never false

+

807 m = re.search(r"^<cog ([^:]+):(\d+)>$", filename) 

+

808 if m: 808 ↛ 809line 808 didn't jump to line 809, because the condition on line 808 was never true

+

809 if lineno <= len(prolines): 

+

810 filename = '<prologue>' 

+

811 source = prolines[lineno-1] 

+

812 lineno -= 1 # Because "import cog" is the first line in the prologue 

+

813 else: 

+

814 filename, coglineno = m.groups() 

+

815 coglineno = int(coglineno) 

+

816 lineno += coglineno - len(prolines) 

+

817 source = linecache.getline(filename, lineno).strip() 

+

818 yield filename, lineno, funcname, source 

+

819 

+

820 

+

821def main(): 

+

822 """Main function for entry_points to use.""" 

+

823 return Cog().main(sys.argv) 

diff --git a/doc/sample_html/d_7b071bdc2a35fa80_makefiles_py.html b/doc/sample_html/d_7b071bdc2a35fa80_makefiles_py.html index 025c4d915..30d129f3e 100644 --- a/doc/sample_html/d_7b071bdc2a35fa80_makefiles_py.html +++ b/doc/sample_html/d_7b071bdc2a35fa80_makefiles_py.html @@ -109,8 +109,8 @@

diff --git a/doc/sample_html/d_7b071bdc2a35fa80_test_cogapp_py.html b/doc/sample_html/d_7b071bdc2a35fa80_test_cogapp_py.html index dca4d1b2f..cf7748b7f 100644 --- a/doc/sample_html/d_7b071bdc2a35fa80_test_cogapp_py.html +++ b/doc/sample_html/d_7b071bdc2a35fa80_test_cogapp_py.html @@ -3,7 +3,7 @@ - Coverage for cogapp/test_cogapp.py: 30.07% + Coverage for cogapp/test_cogapp.py: 29.94% @@ -13,7 +13,7 @@

Coverage for cogapp/test_cogapp.py: - 30.07% + 29.94%

@@ -44,9 +44,9 @@

- 788 statements   - - + 795 statements   + +

@@ -1079,74 +1079,74 @@

1018 output = self.output.getvalue() 

1019 self.assertIn("(changed)", output) 

1020 

-

1021 def testWildcards(self): 

+

1021 def testPrintOutput(self): 

1022 d = { 

1023 'test.cog': """\ 

1024 // This is my C++ file. 

1025 //[[[cog 

1026 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

1027 for fn in fnames: 

-

1028 cog.outl("void %s();" % fn) 

+

1028 print("void %s();" % fn) 

1029 //]]] 

1030 //[[[end]]] 

1031 """, 

1032 

-

1033 'test2.cog': """\ 

+

1033 'test.out': """\ 

1034 // This is my C++ file. 

1035 //[[[cog 

1036 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

1037 for fn in fnames: 

-

1038 cog.outl("void %s();" % fn) 

+

1038 print("void %s();" % fn) 

1039 //]]] 

-

1040 //[[[end]]] 

-

1041 """, 

-

1042 

-

1043 'test.out': """\ 

-

1044 // This is my C++ file. 

-

1045 //[[[cog 

-

1046 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

-

1047 for fn in fnames: 

-

1048 cog.outl("void %s();" % fn) 

-

1049 //]]] 

-

1050 void DoSomething(); 

-

1051 void DoAnotherThing(); 

-

1052 void DoLastThing(); 

-

1053 //[[[end]]] 

-

1054 """, 

-

1055 

-

1056 'not_this_one.cog': """\ 

-

1057 // This is my C++ file. 

-

1058 //[[[cog 

-

1059 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

-

1060 for fn in fnames: 

-

1061 cog.outl("void %s();" % fn) 

-

1062 //]]] 

-

1063 //[[[end]]] 

-

1064 """, 

-

1065 

-

1066 'not_this_one.out': """\ 

-

1067 // This is my C++ file. 

-

1068 //[[[cog 

-

1069 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

-

1070 for fn in fnames: 

-

1071 cog.outl("void %s();" % fn) 

-

1072 //]]] 

-

1073 //[[[end]]] 

-

1074 """, 

-

1075 } 

-

1076 

-

1077 makeFiles(d) 

-

1078 self.cog.callableMain(['argv0', '-r', 't*.cog']) 

-

1079 self.assertFilesSame('test.cog', 'test.out') 

-

1080 self.assertFilesSame('test2.cog', 'test.out') 

-

1081 self.assertFilesSame('not_this_one.cog', 'not_this_one.out') 

-

1082 output = self.output.getvalue() 

-

1083 self.assertIn("(changed)", output) 

-

1084 

-

1085 def testOutputFile(self): 

-

1086 # -o sets the output file. 

-

1087 d = { 

-

1088 'test.cog': """\ 

+

1040 void DoSomething(); 

+

1041 void DoAnotherThing(); 

+

1042 void DoLastThing(); 

+

1043 //[[[end]]] 

+

1044 """, 

+

1045 } 

+

1046 

+

1047 makeFiles(d) 

+

1048 self.cog.callableMain(['argv0', '-rP', 'test.cog']) 

+

1049 self.assertFilesSame('test.cog', 'test.out') 

+

1050 output = self.output.getvalue() 

+

1051 self.assertIn("(changed)", output) 

+

1052 

+

1053 def testWildcards(self): 

+

1054 d = { 

+

1055 'test.cog': """\ 

+

1056 // This is my C++ file. 

+

1057 //[[[cog 

+

1058 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

+

1059 for fn in fnames: 

+

1060 cog.outl("void %s();" % fn) 

+

1061 //]]] 

+

1062 //[[[end]]] 

+

1063 """, 

+

1064 

+

1065 'test2.cog': """\ 

+

1066 // This is my C++ file. 

+

1067 //[[[cog 

+

1068 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

+

1069 for fn in fnames: 

+

1070 cog.outl("void %s();" % fn) 

+

1071 //]]] 

+

1072 //[[[end]]] 

+

1073 """, 

+

1074 

+

1075 'test.out': """\ 

+

1076 // This is my C++ file. 

+

1077 //[[[cog 

+

1078 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

+

1079 for fn in fnames: 

+

1080 cog.outl("void %s();" % fn) 

+

1081 //]]] 

+

1082 void DoSomething(); 

+

1083 void DoAnotherThing(); 

+

1084 void DoLastThing(); 

+

1085 //[[[end]]] 

+

1086 """, 

+

1087 

+

1088 'not_this_one.cog': """\ 

1089 // This is my C++ file. 

1090 //[[[cog 

1091 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

@@ -1156,1393 +1156,1425 @@

1095 //[[[end]]] 

1096 """, 

1097 

-

1098 'test.out': """\ 

+

1098 'not_this_one.out': """\ 

1099 // This is my C++ file. 

1100 //[[[cog 

1101 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

1102 for fn in fnames: 

1103 cog.outl("void %s();" % fn) 

1104 //]]] 

-

1105 void DoSomething(); 

-

1106 void DoAnotherThing(); 

-

1107 void DoLastThing(); 

-

1108 //[[[end]]] 

-

1109 """, 

-

1110 } 

-

1111 

-

1112 makeFiles(d) 

-

1113 self.cog.callableMain(['argv0', '-o', 'in/a/dir/test.cogged', 'test.cog']) 

-

1114 self.assertFilesSame('in/a/dir/test.cogged', 'test.out') 

-

1115 

-

1116 def testAtFile(self): 

-

1117 d = { 

-

1118 'one.cog': """\ 

-

1119 //[[[cog 

-

1120 cog.outl("hello world") 

-

1121 //]]] 

-

1122 //[[[end]]] 

-

1123 """, 

-

1124 

-

1125 'one.out': """\ 

-

1126 //[[[cog 

-

1127 cog.outl("hello world") 

-

1128 //]]] 

-

1129 hello world 

-

1130 //[[[end]]] 

-

1131 """, 

-

1132 

-

1133 'two.cog': """\ 

-

1134 //[[[cog 

-

1135 cog.outl("goodbye cruel world") 

+

1105 //[[[end]]] 

+

1106 """, 

+

1107 } 

+

1108 

+

1109 makeFiles(d) 

+

1110 self.cog.callableMain(['argv0', '-r', 't*.cog']) 

+

1111 self.assertFilesSame('test.cog', 'test.out') 

+

1112 self.assertFilesSame('test2.cog', 'test.out') 

+

1113 self.assertFilesSame('not_this_one.cog', 'not_this_one.out') 

+

1114 output = self.output.getvalue() 

+

1115 self.assertIn("(changed)", output) 

+

1116 

+

1117 def testOutputFile(self): 

+

1118 # -o sets the output file. 

+

1119 d = { 

+

1120 'test.cog': """\ 

+

1121 // This is my C++ file. 

+

1122 //[[[cog 

+

1123 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

+

1124 for fn in fnames: 

+

1125 cog.outl("void %s();" % fn) 

+

1126 //]]] 

+

1127 //[[[end]]] 

+

1128 """, 

+

1129 

+

1130 'test.out': """\ 

+

1131 // This is my C++ file. 

+

1132 //[[[cog 

+

1133 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

+

1134 for fn in fnames: 

+

1135 cog.outl("void %s();" % fn) 

1136 //]]] 

-

1137 //[[[end]]] 

-

1138 """, 

-

1139 

-

1140 'two.out': """\ 

-

1141 //[[[cog 

-

1142 cog.outl("goodbye cruel world") 

-

1143 //]]] 

-

1144 goodbye cruel world 

-

1145 //[[[end]]] 

-

1146 """, 

+

1137 void DoSomething(); 

+

1138 void DoAnotherThing(); 

+

1139 void DoLastThing(); 

+

1140 //[[[end]]] 

+

1141 """, 

+

1142 } 

+

1143 

+

1144 makeFiles(d) 

+

1145 self.cog.callableMain(['argv0', '-o', 'in/a/dir/test.cogged', 'test.cog']) 

+

1146 self.assertFilesSame('in/a/dir/test.cogged', 'test.out') 

1147 

-

1148 'cogfiles.txt': """\ 

-

1149 # Please run cog 

-

1150 one.cog 

-

1151 

-

1152 two.cog 

-

1153 """ 

-

1154 } 

-

1155 

-

1156 makeFiles(d) 

-

1157 self.cog.callableMain(['argv0', '-r', '@cogfiles.txt']) 

-

1158 self.assertFilesSame('one.cog', 'one.out') 

-

1159 self.assertFilesSame('two.cog', 'two.out') 

-

1160 output = self.output.getvalue() 

-

1161 self.assertIn("(changed)", output) 

-

1162 

-

1163 def testNestedAtFile(self): 

-

1164 d = { 

-

1165 'one.cog': """\ 

+

1148 def testAtFile(self): 

+

1149 d = { 

+

1150 'one.cog': """\ 

+

1151 //[[[cog 

+

1152 cog.outl("hello world") 

+

1153 //]]] 

+

1154 //[[[end]]] 

+

1155 """, 

+

1156 

+

1157 'one.out': """\ 

+

1158 //[[[cog 

+

1159 cog.outl("hello world") 

+

1160 //]]] 

+

1161 hello world 

+

1162 //[[[end]]] 

+

1163 """, 

+

1164 

+

1165 'two.cog': """\ 

1166 //[[[cog 

-

1167 cog.outl("hello world") 

+

1167 cog.outl("goodbye cruel world") 

1168 //]]] 

1169 //[[[end]]] 

1170 """, 

1171 

-

1172 'one.out': """\ 

+

1172 'two.out': """\ 

1173 //[[[cog 

-

1174 cog.outl("hello world") 

+

1174 cog.outl("goodbye cruel world") 

1175 //]]] 

-

1176 hello world 

+

1176 goodbye cruel world 

1177 //[[[end]]] 

1178 """, 

1179 

-

1180 'two.cog': """\ 

-

1181 //[[[cog 

-

1182 cog.outl("goodbye cruel world") 

-

1183 //]]] 

-

1184 //[[[end]]] 

-

1185 """, 

-

1186 

-

1187 'two.out': """\ 

-

1188 //[[[cog 

-

1189 cog.outl("goodbye cruel world") 

-

1190 //]]] 

-

1191 goodbye cruel world 

-

1192 //[[[end]]] 

-

1193 """, 

+

1180 'cogfiles.txt': """\ 

+

1181 # Please run cog 

+

1182 one.cog 

+

1183 

+

1184 two.cog 

+

1185 """ 

+

1186 } 

+

1187 

+

1188 makeFiles(d) 

+

1189 self.cog.callableMain(['argv0', '-r', '@cogfiles.txt']) 

+

1190 self.assertFilesSame('one.cog', 'one.out') 

+

1191 self.assertFilesSame('two.cog', 'two.out') 

+

1192 output = self.output.getvalue() 

+

1193 self.assertIn("(changed)", output) 

1194 

-

1195 'cogfiles.txt': """\ 

-

1196 # Please run cog 

-

1197 one.cog 

-

1198 @cogfiles2.txt 

-

1199 """, 

-

1200 

-

1201 'cogfiles2.txt': """\ 

-

1202 # This one too, please. 

-

1203 two.cog 

-

1204 """, 

-

1205 } 

-

1206 

-

1207 makeFiles(d) 

-

1208 self.cog.callableMain(['argv0', '-r', '@cogfiles.txt']) 

-

1209 self.assertFilesSame('one.cog', 'one.out') 

-

1210 self.assertFilesSame('two.cog', 'two.out') 

-

1211 output = self.output.getvalue() 

-

1212 self.assertIn("(changed)", output) 

-

1213 

-

1214 def testAtFileWithArgs(self): 

-

1215 d = { 

-

1216 'both.cog': """\ 

-

1217 //[[[cog 

-

1218 cog.outl("one: %s" % ('one' in globals())) 

-

1219 cog.outl("two: %s" % ('two' in globals())) 

-

1220 //]]] 

-

1221 //[[[end]]] 

-

1222 """, 

-

1223 

-

1224 'one.out': """\ 

-

1225 //[[[cog 

-

1226 cog.outl("one: %s" % ('one' in globals())) 

-

1227 cog.outl("two: %s" % ('two' in globals())) 

-

1228 //]]] 

-

1229 one: True // ONE 

-

1230 two: False // ONE 

-

1231 //[[[end]]] 

-

1232 """, 

-

1233 

-

1234 'two.out': """\ 

-

1235 //[[[cog 

-

1236 cog.outl("one: %s" % ('one' in globals())) 

-

1237 cog.outl("two: %s" % ('two' in globals())) 

-

1238 //]]] 

-

1239 one: False // TWO 

-

1240 two: True // TWO 

-

1241 //[[[end]]] 

-

1242 """, 

-

1243 

-

1244 'cogfiles.txt': """\ 

-

1245 # Please run cog 

-

1246 both.cog -o in/a/dir/both.one -s ' // ONE' -D one=x 

-

1247 both.cog -o in/a/dir/both.two -s ' // TWO' -D two=x 

-

1248 """ 

-

1249 } 

-

1250 

-

1251 makeFiles(d) 

-

1252 self.cog.callableMain(['argv0', '@cogfiles.txt']) 

-

1253 self.assertFilesSame('in/a/dir/both.one', 'one.out') 

-

1254 self.assertFilesSame('in/a/dir/both.two', 'two.out') 

+

1195 def testNestedAtFile(self): 

+

1196 d = { 

+

1197 'one.cog': """\ 

+

1198 //[[[cog 

+

1199 cog.outl("hello world") 

+

1200 //]]] 

+

1201 //[[[end]]] 

+

1202 """, 

+

1203 

+

1204 'one.out': """\ 

+

1205 //[[[cog 

+

1206 cog.outl("hello world") 

+

1207 //]]] 

+

1208 hello world 

+

1209 //[[[end]]] 

+

1210 """, 

+

1211 

+

1212 'two.cog': """\ 

+

1213 //[[[cog 

+

1214 cog.outl("goodbye cruel world") 

+

1215 //]]] 

+

1216 //[[[end]]] 

+

1217 """, 

+

1218 

+

1219 'two.out': """\ 

+

1220 //[[[cog 

+

1221 cog.outl("goodbye cruel world") 

+

1222 //]]] 

+

1223 goodbye cruel world 

+

1224 //[[[end]]] 

+

1225 """, 

+

1226 

+

1227 'cogfiles.txt': """\ 

+

1228 # Please run cog 

+

1229 one.cog 

+

1230 @cogfiles2.txt 

+

1231 """, 

+

1232 

+

1233 'cogfiles2.txt': """\ 

+

1234 # This one too, please. 

+

1235 two.cog 

+

1236 """, 

+

1237 } 

+

1238 

+

1239 makeFiles(d) 

+

1240 self.cog.callableMain(['argv0', '-r', '@cogfiles.txt']) 

+

1241 self.assertFilesSame('one.cog', 'one.out') 

+

1242 self.assertFilesSame('two.cog', 'two.out') 

+

1243 output = self.output.getvalue() 

+

1244 self.assertIn("(changed)", output) 

+

1245 

+

1246 def testAtFileWithArgs(self): 

+

1247 d = { 

+

1248 'both.cog': """\ 

+

1249 //[[[cog 

+

1250 cog.outl("one: %s" % ('one' in globals())) 

+

1251 cog.outl("two: %s" % ('two' in globals())) 

+

1252 //]]] 

+

1253 //[[[end]]] 

+

1254 """, 

1255 

-

1256 def testAtFileWithBadArgCombo(self): 

-

1257 d = { 

-

1258 'both.cog': """\ 

-

1259 //[[[cog 

-

1260 cog.outl("one: %s" % ('one' in globals())) 

-

1261 cog.outl("two: %s" % ('two' in globals())) 

-

1262 //]]] 

+

1256 'one.out': """\ 

+

1257 //[[[cog 

+

1258 cog.outl("one: %s" % ('one' in globals())) 

+

1259 cog.outl("two: %s" % ('two' in globals())) 

+

1260 //]]] 

+

1261 one: True // ONE 

+

1262 two: False // ONE 

1263 //[[[end]]] 

1264 """, 

1265 

-

1266 'cogfiles.txt': """\ 

-

1267 # Please run cog 

-

1268 both.cog 

-

1269 both.cog -d # This is bad: -r and -d 

-

1270 """ 

-

1271 } 

-

1272 

-

1273 makeFiles(d) 

-

1274 with self.assertRaisesRegex(CogUsageError, r"^Can't use -d with -r \(or you would delete all your source!\)$"): 

-

1275 self.cog.callableMain(['argv0', '-r', '@cogfiles.txt']) 

-

1276 

-

1277 def testAtFileWithTrickyFilenames(self): 

-

1278 def fix_backslashes(files_txt): 

-

1279 """Make the contents of a files.txt sensitive to the platform.""" 

-

1280 if sys.platform != "win32": 

-

1281 files_txt = files_txt.replace("\\", "/") 

-

1282 return files_txt 

-

1283 

-

1284 d = { 

-

1285 'one 1.cog': """\ 

-

1286 //[[[cog cog.outl("hello world") ]]] 

-

1287 """, 

-

1288 

-

1289 'one.out': """\ 

-

1290 //[[[cog cog.outl("hello world") ]]] 

-

1291 hello world //xxx 

-

1292 """, 

-

1293 

-

1294 'subdir': { 

-

1295 'subback.cog': """\ 

-

1296 //[[[cog cog.outl("down deep with backslashes") ]]] 

-

1297 """, 

-

1298 

-

1299 'subfwd.cog': """\ 

-

1300 //[[[cog cog.outl("down deep with slashes") ]]] 

-

1301 """, 

-

1302 }, 

-

1303 

-

1304 'subback.out': """\ 

-

1305 //[[[cog cog.outl("down deep with backslashes") ]]] 

-

1306 down deep with backslashes //yyy 

-

1307 """, 

+

1266 'two.out': """\ 

+

1267 //[[[cog 

+

1268 cog.outl("one: %s" % ('one' in globals())) 

+

1269 cog.outl("two: %s" % ('two' in globals())) 

+

1270 //]]] 

+

1271 one: False // TWO 

+

1272 two: True // TWO 

+

1273 //[[[end]]] 

+

1274 """, 

+

1275 

+

1276 'cogfiles.txt': """\ 

+

1277 # Please run cog 

+

1278 both.cog -o in/a/dir/both.one -s ' // ONE' -D one=x 

+

1279 both.cog -o in/a/dir/both.two -s ' // TWO' -D two=x 

+

1280 """ 

+

1281 } 

+

1282 

+

1283 makeFiles(d) 

+

1284 self.cog.callableMain(['argv0', '@cogfiles.txt']) 

+

1285 self.assertFilesSame('in/a/dir/both.one', 'one.out') 

+

1286 self.assertFilesSame('in/a/dir/both.two', 'two.out') 

+

1287 

+

1288 def testAtFileWithBadArgCombo(self): 

+

1289 d = { 

+

1290 'both.cog': """\ 

+

1291 //[[[cog 

+

1292 cog.outl("one: %s" % ('one' in globals())) 

+

1293 cog.outl("two: %s" % ('two' in globals())) 

+

1294 //]]] 

+

1295 //[[[end]]] 

+

1296 """, 

+

1297 

+

1298 'cogfiles.txt': """\ 

+

1299 # Please run cog 

+

1300 both.cog 

+

1301 both.cog -d # This is bad: -r and -d 

+

1302 """ 

+

1303 } 

+

1304 

+

1305 makeFiles(d) 

+

1306 with self.assertRaisesRegex(CogUsageError, r"^Can't use -d with -r \(or you would delete all your source!\)$"): 

+

1307 self.cog.callableMain(['argv0', '-r', '@cogfiles.txt']) 

1308 

-

1309 'subfwd.out': """\ 

-

1310 //[[[cog cog.outl("down deep with slashes") ]]] 

-

1311 down deep with slashes //zzz 

-

1312 """, 

-

1313 

-

1314 'cogfiles.txt': fix_backslashes("""\ 

-

1315 # Please run cog 

-

1316 'one 1.cog' -s ' //xxx' 

-

1317 subdir\\subback.cog -s ' //yyy' 

-

1318 subdir/subfwd.cog -s ' //zzz' 

-

1319 """) 

-

1320 } 

-

1321 

-

1322 makeFiles(d) 

-

1323 self.cog.callableMain(['argv0', '-z', '-r', '@cogfiles.txt']) 

-

1324 self.assertFilesSame('one 1.cog', 'one.out') 

-

1325 self.assertFilesSame('subdir/subback.cog', 'subback.out') 

-

1326 self.assertFilesSame('subdir/subfwd.cog', 'subfwd.out') 

-

1327 

-

1328 def run_with_verbosity(self, verbosity): 

-

1329 d = { 

-

1330 'unchanged.cog': """\ 

-

1331 //[[[cog 

-

1332 cog.outl("hello world") 

-

1333 //]]] 

-

1334 hello world 

-

1335 //[[[end]]] 

-

1336 """, 

-

1337 

-

1338 'changed.cog': """\ 

-

1339 //[[[cog 

-

1340 cog.outl("goodbye cruel world") 

-

1341 //]]] 

-

1342 //[[[end]]] 

-

1343 """, 

-

1344 

-

1345 'cogfiles.txt': """\ 

-

1346 unchanged.cog 

-

1347 changed.cog 

-

1348 """ 

-

1349 } 

-

1350 

-

1351 makeFiles(d) 

-

1352 self.cog.callableMain(['argv0', '-r', '--verbosity='+verbosity, '@cogfiles.txt']) 

-

1353 output = self.output.getvalue() 

-

1354 return output 

-

1355 

-

1356 def test_verbosity0(self): 

-

1357 output = self.run_with_verbosity("0") 

-

1358 self.assertEqual(output, "") 

+

1309 def testAtFileWithTrickyFilenames(self): 

+

1310 def fix_backslashes(files_txt): 

+

1311 """Make the contents of a files.txt sensitive to the platform.""" 

+

1312 if sys.platform != "win32": 

+

1313 files_txt = files_txt.replace("\\", "/") 

+

1314 return files_txt 

+

1315 

+

1316 d = { 

+

1317 'one 1.cog': """\ 

+

1318 //[[[cog cog.outl("hello world") ]]] 

+

1319 """, 

+

1320 

+

1321 'one.out': """\ 

+

1322 //[[[cog cog.outl("hello world") ]]] 

+

1323 hello world //xxx 

+

1324 """, 

+

1325 

+

1326 'subdir': { 

+

1327 'subback.cog': """\ 

+

1328 //[[[cog cog.outl("down deep with backslashes") ]]] 

+

1329 """, 

+

1330 

+

1331 'subfwd.cog': """\ 

+

1332 //[[[cog cog.outl("down deep with slashes") ]]] 

+

1333 """, 

+

1334 }, 

+

1335 

+

1336 'subback.out': """\ 

+

1337 //[[[cog cog.outl("down deep with backslashes") ]]] 

+

1338 down deep with backslashes //yyy 

+

1339 """, 

+

1340 

+

1341 'subfwd.out': """\ 

+

1342 //[[[cog cog.outl("down deep with slashes") ]]] 

+

1343 down deep with slashes //zzz 

+

1344 """, 

+

1345 

+

1346 'cogfiles.txt': fix_backslashes("""\ 

+

1347 # Please run cog 

+

1348 'one 1.cog' -s ' //xxx' 

+

1349 subdir\\subback.cog -s ' //yyy' 

+

1350 subdir/subfwd.cog -s ' //zzz' 

+

1351 """) 

+

1352 } 

+

1353 

+

1354 makeFiles(d) 

+

1355 self.cog.callableMain(['argv0', '-z', '-r', '@cogfiles.txt']) 

+

1356 self.assertFilesSame('one 1.cog', 'one.out') 

+

1357 self.assertFilesSame('subdir/subback.cog', 'subback.out') 

+

1358 self.assertFilesSame('subdir/subfwd.cog', 'subfwd.out') 

1359 

-

1360 def test_verbosity1(self): 

-

1361 output = self.run_with_verbosity("1") 

-

1362 self.assertEqual(output, "Cogging changed.cog (changed)\n") 

-

1363 

-

1364 def test_verbosity2(self): 

-

1365 output = self.run_with_verbosity("2") 

-

1366 self.assertEqual(output, "Cogging unchanged.cog\nCogging changed.cog (changed)\n") 

-

1367 

-

1368 

-

1369class CogTestLineEndings(TestCaseWithTempDir): 

-

1370 """Tests for -U option (force LF line-endings in output).""" 

-

1371 

-

1372 lines_in = ['Some text.', 

-

1373 '//[[[cog', 

-

1374 'cog.outl("Cog text")', 

-

1375 '//]]]', 

-

1376 'gobbledegook.', 

-

1377 '//[[[end]]]', 

-

1378 'epilogue.', 

-

1379 ''] 

-

1380 

-

1381 lines_out = ['Some text.', 

-

1382 '//[[[cog', 

-

1383 'cog.outl("Cog text")', 

-

1384 '//]]]', 

-

1385 'Cog text', 

-

1386 '//[[[end]]]', 

-

1387 'epilogue.', 

-

1388 ''] 

-

1389 

-

1390 def testOutputNativeEol(self): 

-

1391 makeFiles({'infile': '\n'.join(self.lines_in)}) 

-

1392 self.cog.callableMain(['argv0', '-o', 'outfile', 'infile']) 

-

1393 self.assertFileContent('outfile', os.linesep.join(self.lines_out)) 

-

1394 

-

1395 def testOutputLfEol(self): 

-

1396 makeFiles({'infile': '\n'.join(self.lines_in)}) 

-

1397 self.cog.callableMain(['argv0', '-U', '-o', 'outfile', 'infile']) 

-

1398 self.assertFileContent('outfile', '\n'.join(self.lines_out)) 

+

1360 def run_with_verbosity(self, verbosity): 

+

1361 d = { 

+

1362 'unchanged.cog': """\ 

+

1363 //[[[cog 

+

1364 cog.outl("hello world") 

+

1365 //]]] 

+

1366 hello world 

+

1367 //[[[end]]] 

+

1368 """, 

+

1369 

+

1370 'changed.cog': """\ 

+

1371 //[[[cog 

+

1372 cog.outl("goodbye cruel world") 

+

1373 //]]] 

+

1374 //[[[end]]] 

+

1375 """, 

+

1376 

+

1377 'cogfiles.txt': """\ 

+

1378 unchanged.cog 

+

1379 changed.cog 

+

1380 """ 

+

1381 } 

+

1382 

+

1383 makeFiles(d) 

+

1384 self.cog.callableMain(['argv0', '-r', '--verbosity='+verbosity, '@cogfiles.txt']) 

+

1385 output = self.output.getvalue() 

+

1386 return output 

+

1387 

+

1388 def test_verbosity0(self): 

+

1389 output = self.run_with_verbosity("0") 

+

1390 self.assertEqual(output, "") 

+

1391 

+

1392 def test_verbosity1(self): 

+

1393 output = self.run_with_verbosity("1") 

+

1394 self.assertEqual(output, "Cogging changed.cog (changed)\n") 

+

1395 

+

1396 def test_verbosity2(self): 

+

1397 output = self.run_with_verbosity("2") 

+

1398 self.assertEqual(output, "Cogging unchanged.cog\nCogging changed.cog (changed)\n") 

1399 

-

1400 def testReplaceNativeEol(self): 

-

1401 makeFiles({'test.cog': '\n'.join(self.lines_in)}) 

-

1402 self.cog.callableMain(['argv0', '-r', 'test.cog']) 

-

1403 self.assertFileContent('test.cog', os.linesep.join(self.lines_out)) 

-

1404 

-

1405 def testReplaceLfEol(self): 

-

1406 makeFiles({'test.cog': '\n'.join(self.lines_in)}) 

-

1407 self.cog.callableMain(['argv0', '-U', '-r', 'test.cog']) 

-

1408 self.assertFileContent('test.cog', '\n'.join(self.lines_out)) 

-

1409 

-

1410 

-

1411class CogTestCharacterEncoding(TestCaseWithTempDir): 

+

1400 

+

1401class CogTestLineEndings(TestCaseWithTempDir): 

+

1402 """Tests for -U option (force LF line-endings in output).""" 

+

1403 

+

1404 lines_in = ['Some text.', 

+

1405 '//[[[cog', 

+

1406 'cog.outl("Cog text")', 

+

1407 '//]]]', 

+

1408 'gobbledegook.', 

+

1409 '//[[[end]]]', 

+

1410 'epilogue.', 

+

1411 ''] 

1412 

-

1413 def testSimple(self): 

-

1414 d = { 

-

1415 'test.cog': b"""\ 

-

1416 // This is my C++ file. 

-

1417 //[[[cog 

-

1418 cog.outl("// Unicode: \xe1\x88\xb4 (U+1234)") 

-

1419 //]]] 

-

1420 //[[[end]]] 

-

1421 """, 

-

1422 

-

1423 'test.out': b"""\ 

-

1424 // This is my C++ file. 

-

1425 //[[[cog 

-

1426 cog.outl("// Unicode: \xe1\x88\xb4 (U+1234)") 

-

1427 //]]] 

-

1428 // Unicode: \xe1\x88\xb4 (U+1234) 

-

1429 //[[[end]]] 

-

1430 """.replace(b"\n", os.linesep.encode()), 

-

1431 } 

-

1432 

-

1433 makeFiles(d, bytes=True) 

+

1413 lines_out = ['Some text.', 

+

1414 '//[[[cog', 

+

1415 'cog.outl("Cog text")', 

+

1416 '//]]]', 

+

1417 'Cog text', 

+

1418 '//[[[end]]]', 

+

1419 'epilogue.', 

+

1420 ''] 

+

1421 

+

1422 def testOutputNativeEol(self): 

+

1423 makeFiles({'infile': '\n'.join(self.lines_in)}) 

+

1424 self.cog.callableMain(['argv0', '-o', 'outfile', 'infile']) 

+

1425 self.assertFileContent('outfile', os.linesep.join(self.lines_out)) 

+

1426 

+

1427 def testOutputLfEol(self): 

+

1428 makeFiles({'infile': '\n'.join(self.lines_in)}) 

+

1429 self.cog.callableMain(['argv0', '-U', '-o', 'outfile', 'infile']) 

+

1430 self.assertFileContent('outfile', '\n'.join(self.lines_out)) 

+

1431 

+

1432 def testReplaceNativeEol(self): 

+

1433 makeFiles({'test.cog': '\n'.join(self.lines_in)}) 

1434 self.cog.callableMain(['argv0', '-r', 'test.cog']) 

-

1435 self.assertFilesSame('test.cog', 'test.out') 

-

1436 output = self.output.getvalue() 

-

1437 self.assertIn("(changed)", output) 

-

1438 

-

1439 def testFileEncodingOption(self): 

-

1440 d = { 

-

1441 'test.cog': b"""\ 

-

1442 // \xca\xee\xe4\xe8\xf0\xe2\xea\xe0 Windows 

-

1443 //[[[cog 

-

1444 cog.outl("\xd1\xfa\xe5\xf8\xfc \xe5\xf9\xb8 \xfd\xf2\xe8\xf5 \xec\xff\xe3\xea\xe8\xf5 \xf4\xf0\xe0\xed\xf6\xf3\xe7\xf1\xea\xe8\xf5 \xe1\xf3\xeb\xee\xea \xe4\xe0 \xe2\xfb\xef\xe5\xe9 \xf7\xe0\xfe") 

-

1445 //]]] 

-

1446 //[[[end]]] 

-

1447 """, 

-

1448 

-

1449 'test.out': b"""\ 

-

1450 // \xca\xee\xe4\xe8\xf0\xe2\xea\xe0 Windows 

-

1451 //[[[cog 

-

1452 cog.outl("\xd1\xfa\xe5\xf8\xfc \xe5\xf9\xb8 \xfd\xf2\xe8\xf5 \xec\xff\xe3\xea\xe8\xf5 \xf4\xf0\xe0\xed\xf6\xf3\xe7\xf1\xea\xe8\xf5 \xe1\xf3\xeb\xee\xea \xe4\xe0 \xe2\xfb\xef\xe5\xe9 \xf7\xe0\xfe") 

-

1453 //]]] 

-

1454 \xd1\xfa\xe5\xf8\xfc \xe5\xf9\xb8 \xfd\xf2\xe8\xf5 \xec\xff\xe3\xea\xe8\xf5 \xf4\xf0\xe0\xed\xf6\xf3\xe7\xf1\xea\xe8\xf5 \xe1\xf3\xeb\xee\xea \xe4\xe0 \xe2\xfb\xef\xe5\xe9 \xf7\xe0\xfe 

-

1455 //[[[end]]] 

-

1456 """.replace(b"\n", os.linesep.encode()), 

-

1457 } 

-

1458 

-

1459 makeFiles(d, bytes=True) 

-

1460 self.cog.callableMain(['argv0', '-n', 'cp1251', '-r', 'test.cog']) 

-

1461 self.assertFilesSame('test.cog', 'test.out') 

-

1462 output = self.output.getvalue() 

-

1463 self.assertIn("(changed)", output) 

+

1435 self.assertFileContent('test.cog', os.linesep.join(self.lines_out)) 

+

1436 

+

1437 def testReplaceLfEol(self): 

+

1438 makeFiles({'test.cog': '\n'.join(self.lines_in)}) 

+

1439 self.cog.callableMain(['argv0', '-U', '-r', 'test.cog']) 

+

1440 self.assertFileContent('test.cog', '\n'.join(self.lines_out)) 

+

1441 

+

1442 

+

1443class CogTestCharacterEncoding(TestCaseWithTempDir): 

+

1444 

+

1445 def testSimple(self): 

+

1446 d = { 

+

1447 'test.cog': b"""\ 

+

1448 // This is my C++ file. 

+

1449 //[[[cog 

+

1450 cog.outl("// Unicode: \xe1\x88\xb4 (U+1234)") 

+

1451 //]]] 

+

1452 //[[[end]]] 

+

1453 """, 

+

1454 

+

1455 'test.out': b"""\ 

+

1456 // This is my C++ file. 

+

1457 //[[[cog 

+

1458 cog.outl("// Unicode: \xe1\x88\xb4 (U+1234)") 

+

1459 //]]] 

+

1460 // Unicode: \xe1\x88\xb4 (U+1234) 

+

1461 //[[[end]]] 

+

1462 """.replace(b"\n", os.linesep.encode()), 

+

1463 } 

1464 

-

1465 

-

1466class TestCaseWithImports(TestCaseWithTempDir): 

-

1467 """ When running tests which import modules, the sys.modules list 

-

1468 leaks from one test to the next. This test case class scrubs 

-

1469 the list after each run to keep the tests isolated from each other. 

-

1470 """ 

-

1471 

-

1472 def setUp(self): 

-

1473 super(TestCaseWithImports, self).setUp() 

-

1474 self.sysmodulekeys = list(sys.modules) 

-

1475 

-

1476 def tearDown(self): 

-

1477 modstoscrub = [ 

-

1478 modname 

-

1479 for modname in sys.modules 

-

1480 if modname not in self.sysmodulekeys 

-

1481 ] 

-

1482 for modname in modstoscrub: 

-

1483 del sys.modules[modname] 

-

1484 super(TestCaseWithImports, self).tearDown() 

-

1485 

-

1486 

-

1487class CogIncludeTests(TestCaseWithImports): 

-

1488 dincludes = { 

-

1489 'test.cog': """\ 

-

1490 //[[[cog 

-

1491 import mymodule 

-

1492 //]]] 

-

1493 //[[[end]]] 

-

1494 """, 

-

1495 

-

1496 'test.out': """\ 

-

1497 //[[[cog 

-

1498 import mymodule 

-

1499 //]]] 

-

1500 Hello from mymodule 

-

1501 //[[[end]]] 

-

1502 """, 

+

1465 makeFiles(d, bytes=True) 

+

1466 self.cog.callableMain(['argv0', '-r', 'test.cog']) 

+

1467 self.assertFilesSame('test.cog', 'test.out') 

+

1468 output = self.output.getvalue() 

+

1469 self.assertIn("(changed)", output) 

+

1470 

+

1471 def testFileEncodingOption(self): 

+

1472 d = { 

+

1473 'test.cog': b"""\ 

+

1474 // \xca\xee\xe4\xe8\xf0\xe2\xea\xe0 Windows 

+

1475 //[[[cog 

+

1476 cog.outl("\xd1\xfa\xe5\xf8\xfc \xe5\xf9\xb8 \xfd\xf2\xe8\xf5 \xec\xff\xe3\xea\xe8\xf5 \xf4\xf0\xe0\xed\xf6\xf3\xe7\xf1\xea\xe8\xf5 \xe1\xf3\xeb\xee\xea \xe4\xe0 \xe2\xfb\xef\xe5\xe9 \xf7\xe0\xfe") 

+

1477 //]]] 

+

1478 //[[[end]]] 

+

1479 """, 

+

1480 

+

1481 'test.out': b"""\ 

+

1482 // \xca\xee\xe4\xe8\xf0\xe2\xea\xe0 Windows 

+

1483 //[[[cog 

+

1484 cog.outl("\xd1\xfa\xe5\xf8\xfc \xe5\xf9\xb8 \xfd\xf2\xe8\xf5 \xec\xff\xe3\xea\xe8\xf5 \xf4\xf0\xe0\xed\xf6\xf3\xe7\xf1\xea\xe8\xf5 \xe1\xf3\xeb\xee\xea \xe4\xe0 \xe2\xfb\xef\xe5\xe9 \xf7\xe0\xfe") 

+

1485 //]]] 

+

1486 \xd1\xfa\xe5\xf8\xfc \xe5\xf9\xb8 \xfd\xf2\xe8\xf5 \xec\xff\xe3\xea\xe8\xf5 \xf4\xf0\xe0\xed\xf6\xf3\xe7\xf1\xea\xe8\xf5 \xe1\xf3\xeb\xee\xea \xe4\xe0 \xe2\xfb\xef\xe5\xe9 \xf7\xe0\xfe 

+

1487 //[[[end]]] 

+

1488 """.replace(b"\n", os.linesep.encode()), 

+

1489 } 

+

1490 

+

1491 makeFiles(d, bytes=True) 

+

1492 self.cog.callableMain(['argv0', '-n', 'cp1251', '-r', 'test.cog']) 

+

1493 self.assertFilesSame('test.cog', 'test.out') 

+

1494 output = self.output.getvalue() 

+

1495 self.assertIn("(changed)", output) 

+

1496 

+

1497 

+

1498class TestCaseWithImports(TestCaseWithTempDir): 

+

1499 """ When running tests which import modules, the sys.modules list 

+

1500 leaks from one test to the next. This test case class scrubs 

+

1501 the list after each run to keep the tests isolated from each other. 

+

1502 """ 

1503 

-

1504 'test2.out': """\ 

-

1505 //[[[cog 

-

1506 import mymodule 

-

1507 //]]] 

-

1508 Hello from mymodule in inc2 

-

1509 //[[[end]]] 

-

1510 """, 

-

1511 

-

1512 'include': { 

-

1513 'mymodule.py': """\ 

-

1514 import cog 

-

1515 cog.outl("Hello from mymodule") 

-

1516 """ 

-

1517 }, 

+

1504 def setUp(self): 

+

1505 super(TestCaseWithImports, self).setUp() 

+

1506 self.sysmodulekeys = list(sys.modules) 

+

1507 

+

1508 def tearDown(self): 

+

1509 modstoscrub = [ 

+

1510 modname 

+

1511 for modname in sys.modules 

+

1512 if modname not in self.sysmodulekeys 

+

1513 ] 

+

1514 for modname in modstoscrub: 

+

1515 del sys.modules[modname] 

+

1516 super(TestCaseWithImports, self).tearDown() 

+

1517 

1518 

-

1519 'inc2': { 

-

1520 'mymodule.py': """\ 

-

1521 import cog 

-

1522 cog.outl("Hello from mymodule in inc2") 

-

1523 """ 

-

1524 }, 

-

1525 

-

1526 'inc3': { 

-

1527 'someothermodule.py': """\ 

-

1528 import cog 

-

1529 cog.outl("This is some other module.") 

-

1530 """ 

-

1531 }, 

-

1532 } 

-

1533 

-

1534 def testNeedIncludePath(self): 

-

1535 # Try it without the -I, to see that an ImportError happens. 

-

1536 makeFiles(self.dincludes) 

-

1537 msg = "(ImportError|ModuleNotFoundError): No module named '?mymodule'?" 

-

1538 with self.assertRaisesRegex(CogUserException, msg): 

-

1539 self.cog.callableMain(['argv0', '-r', 'test.cog']) 

-

1540 

-

1541 def testIncludePath(self): 

-

1542 # Test that -I adds include directories properly. 

-

1543 makeFiles(self.dincludes) 

-

1544 self.cog.callableMain(['argv0', '-r', '-I', 'include', 'test.cog']) 

-

1545 self.assertFilesSame('test.cog', 'test.out') 

-

1546 

-

1547 def testTwoIncludePaths(self): 

-

1548 # Test that two -I's add include directories properly. 

-

1549 makeFiles(self.dincludes) 

-

1550 self.cog.callableMain(['argv0', '-r', '-I', 'include', '-I', 'inc2', 'test.cog']) 

-

1551 self.assertFilesSame('test.cog', 'test.out') 

-

1552 

-

1553 def testTwoIncludePaths2(self): 

-

1554 # Test that two -I's add include directories properly. 

-

1555 makeFiles(self.dincludes) 

-

1556 self.cog.callableMain(['argv0', '-r', '-I', 'inc2', '-I', 'include', 'test.cog']) 

-

1557 self.assertFilesSame('test.cog', 'test2.out') 

-

1558 

-

1559 def testUselessIncludePath(self): 

-

1560 # Test that the search will continue past the first directory. 

-

1561 makeFiles(self.dincludes) 

-

1562 self.cog.callableMain(['argv0', '-r', '-I', 'inc3', '-I', 'include', 'test.cog']) 

-

1563 self.assertFilesSame('test.cog', 'test.out') 

-

1564 

-

1565 def testSysPathIsUnchanged(self): 

-

1566 d = { 

-

1567 'bad.cog': """\ 

-

1568 //[[[cog cog.error("Oh no!") ]]] 

-

1569 //[[[end]]] 

-

1570 """, 

-

1571 'good.cog': """\ 

-

1572 //[[[cog cog.outl("Oh yes!") ]]] 

-

1573 //[[[end]]] 

-

1574 """, 

-

1575 } 

-

1576 

-

1577 makeFiles(d) 

-

1578 # Is it unchanged just by creating a cog engine? 

-

1579 oldsyspath = sys.path[:] 

-

1580 self.newCog() 

-

1581 self.assertEqual(oldsyspath, sys.path) 

-

1582 # Is it unchanged for a successful run? 

-

1583 self.newCog() 

-

1584 self.cog.callableMain(['argv0', '-r', 'good.cog']) 

-

1585 self.assertEqual(oldsyspath, sys.path) 

-

1586 # Is it unchanged for a successful run with includes? 

-

1587 self.newCog() 

-

1588 self.cog.callableMain(['argv0', '-r', '-I', 'xyzzy', 'good.cog']) 

-

1589 self.assertEqual(oldsyspath, sys.path) 

-

1590 # Is it unchanged for a successful run with two includes? 

-

1591 self.newCog() 

-

1592 self.cog.callableMain(['argv0', '-r', '-I', 'xyzzy', '-I', 'quux', 'good.cog']) 

-

1593 self.assertEqual(oldsyspath, sys.path) 

-

1594 # Is it unchanged for a failed run? 

-

1595 self.newCog() 

-

1596 with self.assertRaisesRegex(CogError, r"^Oh no!$"): 

-

1597 self.cog.callableMain(['argv0', '-r', 'bad.cog']) 

-

1598 self.assertEqual(oldsyspath, sys.path) 

-

1599 # Is it unchanged for a failed run with includes? 

-

1600 self.newCog() 

-

1601 with self.assertRaisesRegex(CogError, r"^Oh no!$"): 

-

1602 self.cog.callableMain(['argv0', '-r', '-I', 'xyzzy', 'bad.cog']) 

-

1603 self.assertEqual(oldsyspath, sys.path) 

-

1604 # Is it unchanged for a failed run with two includes? 

-

1605 self.newCog() 

-

1606 with self.assertRaisesRegex(CogError, r"^Oh no!$"): 

-

1607 self.cog.callableMain(['argv0', '-r', '-I', 'xyzzy', '-I', 'quux', 'bad.cog']) 

-

1608 self.assertEqual(oldsyspath, sys.path) 

-

1609 

-

1610 def testSubDirectories(self): 

-

1611 # Test that relative paths on the command line work, with includes. 

-

1612 

-

1613 d = { 

-

1614 'code': { 

-

1615 'test.cog': """\ 

-

1616 //[[[cog 

-

1617 import mysubmodule 

-

1618 //]]] 

-

1619 //[[[end]]] 

-

1620 """, 

-

1621 

-

1622 'test.out': """\ 

-

1623 //[[[cog 

-

1624 import mysubmodule 

-

1625 //]]] 

-

1626 Hello from mysubmodule 

-

1627 //[[[end]]] 

-

1628 """, 

-

1629 

-

1630 'mysubmodule.py': """\ 

-

1631 import cog 

-

1632 cog.outl("Hello from mysubmodule") 

-

1633 """ 

-

1634 } 

-

1635 } 

-

1636 

-

1637 makeFiles(d) 

-

1638 # We should be able to invoke cog without the -I switch, and it will 

-

1639 # auto-include the current directory 

-

1640 self.cog.callableMain(['argv0', '-r', 'code/test.cog']) 

-

1641 self.assertFilesSame('code/test.cog', 'code/test.out') 

-

1642 

-

1643 

-

1644class CogTestsInFiles(TestCaseWithTempDir): 

-

1645 

-

1646 def testWarnIfNoCogCode(self): 

-

1647 # Test that the -e switch warns if there is no Cog code. 

-

1648 d = { 

-

1649 'with.cog': """\ 

-

1650 //[[[cog 

-

1651 cog.outl("hello world") 

-

1652 //]]] 

-

1653 hello world 

-

1654 //[[[end]]] 

-

1655 """, 

-

1656 

-

1657 'without.cog': """\ 

-

1658 There's no cog 

-

1659 code in this file. 

-

1660 """, 

-

1661 } 

-

1662 

-

1663 makeFiles(d) 

-

1664 self.cog.callableMain(['argv0', '-e', 'with.cog']) 

-

1665 output = self.output.getvalue() 

-

1666 self.assertNotIn("Warning", output) 

-

1667 self.newCog() 

-

1668 self.cog.callableMain(['argv0', '-e', 'without.cog']) 

-

1669 output = self.output.getvalue() 

-

1670 self.assertIn("Warning: no cog code found in without.cog", output) 

-

1671 self.newCog() 

-

1672 self.cog.callableMain(['argv0', 'without.cog']) 

-

1673 output = self.output.getvalue() 

-

1674 self.assertNotIn("Warning", output) 

+

1519class CogIncludeTests(TestCaseWithImports): 

+

1520 dincludes = { 

+

1521 'test.cog': """\ 

+

1522 //[[[cog 

+

1523 import mymodule 

+

1524 //]]] 

+

1525 //[[[end]]] 

+

1526 """, 

+

1527 

+

1528 'test.out': """\ 

+

1529 //[[[cog 

+

1530 import mymodule 

+

1531 //]]] 

+

1532 Hello from mymodule 

+

1533 //[[[end]]] 

+

1534 """, 

+

1535 

+

1536 'test2.out': """\ 

+

1537 //[[[cog 

+

1538 import mymodule 

+

1539 //]]] 

+

1540 Hello from mymodule in inc2 

+

1541 //[[[end]]] 

+

1542 """, 

+

1543 

+

1544 'include': { 

+

1545 'mymodule.py': """\ 

+

1546 import cog 

+

1547 cog.outl("Hello from mymodule") 

+

1548 """ 

+

1549 }, 

+

1550 

+

1551 'inc2': { 

+

1552 'mymodule.py': """\ 

+

1553 import cog 

+

1554 cog.outl("Hello from mymodule in inc2") 

+

1555 """ 

+

1556 }, 

+

1557 

+

1558 'inc3': { 

+

1559 'someothermodule.py': """\ 

+

1560 import cog 

+

1561 cog.outl("This is some other module.") 

+

1562 """ 

+

1563 }, 

+

1564 } 

+

1565 

+

1566 def testNeedIncludePath(self): 

+

1567 # Try it without the -I, to see that an ImportError happens. 

+

1568 makeFiles(self.dincludes) 

+

1569 msg = "(ImportError|ModuleNotFoundError): No module named '?mymodule'?" 

+

1570 with self.assertRaisesRegex(CogUserException, msg): 

+

1571 self.cog.callableMain(['argv0', '-r', 'test.cog']) 

+

1572 

+

1573 def testIncludePath(self): 

+

1574 # Test that -I adds include directories properly. 

+

1575 makeFiles(self.dincludes) 

+

1576 self.cog.callableMain(['argv0', '-r', '-I', 'include', 'test.cog']) 

+

1577 self.assertFilesSame('test.cog', 'test.out') 

+

1578 

+

1579 def testTwoIncludePaths(self): 

+

1580 # Test that two -I's add include directories properly. 

+

1581 makeFiles(self.dincludes) 

+

1582 self.cog.callableMain(['argv0', '-r', '-I', 'include', '-I', 'inc2', 'test.cog']) 

+

1583 self.assertFilesSame('test.cog', 'test.out') 

+

1584 

+

1585 def testTwoIncludePaths2(self): 

+

1586 # Test that two -I's add include directories properly. 

+

1587 makeFiles(self.dincludes) 

+

1588 self.cog.callableMain(['argv0', '-r', '-I', 'inc2', '-I', 'include', 'test.cog']) 

+

1589 self.assertFilesSame('test.cog', 'test2.out') 

+

1590 

+

1591 def testUselessIncludePath(self): 

+

1592 # Test that the search will continue past the first directory. 

+

1593 makeFiles(self.dincludes) 

+

1594 self.cog.callableMain(['argv0', '-r', '-I', 'inc3', '-I', 'include', 'test.cog']) 

+

1595 self.assertFilesSame('test.cog', 'test.out') 

+

1596 

+

1597 def testSysPathIsUnchanged(self): 

+

1598 d = { 

+

1599 'bad.cog': """\ 

+

1600 //[[[cog cog.error("Oh no!") ]]] 

+

1601 //[[[end]]] 

+

1602 """, 

+

1603 'good.cog': """\ 

+

1604 //[[[cog cog.outl("Oh yes!") ]]] 

+

1605 //[[[end]]] 

+

1606 """, 

+

1607 } 

+

1608 

+

1609 makeFiles(d) 

+

1610 # Is it unchanged just by creating a cog engine? 

+

1611 oldsyspath = sys.path[:] 

+

1612 self.newCog() 

+

1613 self.assertEqual(oldsyspath, sys.path) 

+

1614 # Is it unchanged for a successful run? 

+

1615 self.newCog() 

+

1616 self.cog.callableMain(['argv0', '-r', 'good.cog']) 

+

1617 self.assertEqual(oldsyspath, sys.path) 

+

1618 # Is it unchanged for a successful run with includes? 

+

1619 self.newCog() 

+

1620 self.cog.callableMain(['argv0', '-r', '-I', 'xyzzy', 'good.cog']) 

+

1621 self.assertEqual(oldsyspath, sys.path) 

+

1622 # Is it unchanged for a successful run with two includes? 

+

1623 self.newCog() 

+

1624 self.cog.callableMain(['argv0', '-r', '-I', 'xyzzy', '-I', 'quux', 'good.cog']) 

+

1625 self.assertEqual(oldsyspath, sys.path) 

+

1626 # Is it unchanged for a failed run? 

+

1627 self.newCog() 

+

1628 with self.assertRaisesRegex(CogError, r"^Oh no!$"): 

+

1629 self.cog.callableMain(['argv0', '-r', 'bad.cog']) 

+

1630 self.assertEqual(oldsyspath, sys.path) 

+

1631 # Is it unchanged for a failed run with includes? 

+

1632 self.newCog() 

+

1633 with self.assertRaisesRegex(CogError, r"^Oh no!$"): 

+

1634 self.cog.callableMain(['argv0', '-r', '-I', 'xyzzy', 'bad.cog']) 

+

1635 self.assertEqual(oldsyspath, sys.path) 

+

1636 # Is it unchanged for a failed run with two includes? 

+

1637 self.newCog() 

+

1638 with self.assertRaisesRegex(CogError, r"^Oh no!$"): 

+

1639 self.cog.callableMain(['argv0', '-r', '-I', 'xyzzy', '-I', 'quux', 'bad.cog']) 

+

1640 self.assertEqual(oldsyspath, sys.path) 

+

1641 

+

1642 def testSubDirectories(self): 

+

1643 # Test that relative paths on the command line work, with includes. 

+

1644 

+

1645 d = { 

+

1646 'code': { 

+

1647 'test.cog': """\ 

+

1648 //[[[cog 

+

1649 import mysubmodule 

+

1650 //]]] 

+

1651 //[[[end]]] 

+

1652 """, 

+

1653 

+

1654 'test.out': """\ 

+

1655 //[[[cog 

+

1656 import mysubmodule 

+

1657 //]]] 

+

1658 Hello from mysubmodule 

+

1659 //[[[end]]] 

+

1660 """, 

+

1661 

+

1662 'mysubmodule.py': """\ 

+

1663 import cog 

+

1664 cog.outl("Hello from mysubmodule") 

+

1665 """ 

+

1666 } 

+

1667 } 

+

1668 

+

1669 makeFiles(d) 

+

1670 # We should be able to invoke cog without the -I switch, and it will 

+

1671 # auto-include the current directory 

+

1672 self.cog.callableMain(['argv0', '-r', 'code/test.cog']) 

+

1673 self.assertFilesSame('code/test.cog', 'code/test.out') 

+

1674 

1675 

-

1676 def testFileNameProps(self): 

-

1677 d = { 

-

1678 'cog1.txt': """\ 

-

1679 //[[[cog 

-

1680 cog.outl("This is %s in, %s out" % (cog.inFile, cog.outFile)) 

-

1681 //]]] 

-

1682 this is cog1.txt in, cog1.txt out 

-

1683 [[[end]]] 

-

1684 """, 

-

1685 

-

1686 'cog1.out': """\ 

-

1687 //[[[cog 

-

1688 cog.outl("This is %s in, %s out" % (cog.inFile, cog.outFile)) 

-

1689 //]]] 

-

1690 This is cog1.txt in, cog1.txt out 

-

1691 [[[end]]] 

+

1676class CogTestsInFiles(TestCaseWithTempDir): 

+

1677 

+

1678 def testWarnIfNoCogCode(self): 

+

1679 # Test that the -e switch warns if there is no Cog code. 

+

1680 d = { 

+

1681 'with.cog': """\ 

+

1682 //[[[cog 

+

1683 cog.outl("hello world") 

+

1684 //]]] 

+

1685 hello world 

+

1686 //[[[end]]] 

+

1687 """, 

+

1688 

+

1689 'without.cog': """\ 

+

1690 There's no cog 

+

1691 code in this file. 

1692 """, 

-

1693 

-

1694 'cog1out.out': """\ 

-

1695 //[[[cog 

-

1696 cog.outl("This is %s in, %s out" % (cog.inFile, cog.outFile)) 

-

1697 //]]] 

-

1698 This is cog1.txt in, cog1out.txt out 

-

1699 [[[end]]] 

-

1700 """, 

-

1701 } 

-

1702 

-

1703 makeFiles(d) 

-

1704 self.cog.callableMain(['argv0', '-r', 'cog1.txt']) 

-

1705 self.assertFilesSame('cog1.txt', 'cog1.out') 

-

1706 self.newCog() 

-

1707 self.cog.callableMain(['argv0', '-o', 'cog1out.txt', 'cog1.txt']) 

-

1708 self.assertFilesSame('cog1out.txt', 'cog1out.out') 

-

1709 

-

1710 def testGlobalsDontCrossFiles(self): 

-

1711 # Make sure that global values don't get shared between files. 

-

1712 d = { 

-

1713 'one.cog': """\ 

-

1714 //[[[cog s = "This was set in one.cog" ]]] 

-

1715 //[[[end]]] 

-

1716 //[[[cog cog.outl(s) ]]] 

-

1717 //[[[end]]] 

-

1718 """, 

-

1719 

-

1720 'one.out': """\ 

-

1721 //[[[cog s = "This was set in one.cog" ]]] 

-

1722 //[[[end]]] 

-

1723 //[[[cog cog.outl(s) ]]] 

-

1724 This was set in one.cog 

-

1725 //[[[end]]] 

-

1726 """, 

-

1727 

-

1728 'two.cog': """\ 

-

1729 //[[[cog 

-

1730 try: 

-

1731 cog.outl(s) 

-

1732 except NameError: 

-

1733 cog.outl("s isn't set!") 

-

1734 //]]] 

-

1735 //[[[end]]] 

-

1736 """, 

-

1737 

-

1738 'two.out': """\ 

-

1739 //[[[cog 

-

1740 try: 

-

1741 cog.outl(s) 

-

1742 except NameError: 

-

1743 cog.outl("s isn't set!") 

-

1744 //]]] 

-

1745 s isn't set! 

-

1746 //[[[end]]] 

-

1747 """, 

-

1748 

-

1749 'cogfiles.txt': """\ 

-

1750 # Please run cog 

-

1751 one.cog 

-

1752 

-

1753 two.cog 

-

1754 """ 

-

1755 } 

-

1756 

-

1757 makeFiles(d) 

-

1758 self.cog.callableMain(['argv0', '-r', '@cogfiles.txt']) 

-

1759 self.assertFilesSame('one.cog', 'one.out') 

-

1760 self.assertFilesSame('two.cog', 'two.out') 

-

1761 output = self.output.getvalue() 

-

1762 self.assertIn("(changed)", output) 

-

1763 

-

1764 def testRemoveGeneratedOutput(self): 

-

1765 d = { 

-

1766 'cog1.txt': """\ 

-

1767 //[[[cog 

-

1768 cog.outl("This line was generated.") 

-

1769 //]]] 

-

1770 This line was generated. 

-

1771 //[[[end]]] 

-

1772 This line was not. 

-

1773 """, 

-

1774 

-

1775 'cog1.out': """\ 

-

1776 //[[[cog 

-

1777 cog.outl("This line was generated.") 

-

1778 //]]] 

-

1779 //[[[end]]] 

-

1780 This line was not. 

-

1781 """, 

-

1782 

-

1783 'cog1.out2': """\ 

-

1784 //[[[cog 

-

1785 cog.outl("This line was generated.") 

-

1786 //]]] 

-

1787 This line was generated. 

-

1788 //[[[end]]] 

-

1789 This line was not. 

-

1790 """, 

-

1791 } 

-

1792 

-

1793 makeFiles(d) 

-

1794 # Remove generated output. 

-

1795 self.cog.callableMain(['argv0', '-r', '-x', 'cog1.txt']) 

-

1796 self.assertFilesSame('cog1.txt', 'cog1.out') 

-

1797 self.newCog() 

-

1798 # Regenerate the generated output. 

-

1799 self.cog.callableMain(['argv0', '-r', 'cog1.txt']) 

-

1800 self.assertFilesSame('cog1.txt', 'cog1.out2') 

-

1801 self.newCog() 

-

1802 # Remove the generated output again. 

-

1803 self.cog.callableMain(['argv0', '-r', '-x', 'cog1.txt']) 

-

1804 self.assertFilesSame('cog1.txt', 'cog1.out') 

-

1805 

-

1806 def testMsgCall(self): 

-

1807 infile = """\ 

-

1808 #[[[cog 

-

1809 cog.msg("Hello there!") 

-

1810 #]]] 

-

1811 #[[[end]]] 

-

1812 """ 

-

1813 infile = reindentBlock(infile) 

-

1814 self.assertEqual(self.cog.processString(infile), infile) 

-

1815 output = self.output.getvalue() 

-

1816 self.assertEqual(output, "Message: Hello there!\n") 

-

1817 

-

1818 def testErrorMessageHasNoTraceback(self): 

-

1819 # Test that a Cog error is printed to stderr with no traceback. 

-

1820 

-

1821 d = { 

-

1822 'cog1.txt': """\ 

-

1823 //[[[cog 

-

1824 cog.outl("This line was newly") 

-

1825 cog.outl("generated by cog") 

-

1826 cog.outl("blah blah.") 

-

1827 //]]] 

-

1828 Xhis line was newly 

-

1829 generated by cog 

-

1830 blah blah. 

-

1831 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

-

1832 """, 

-

1833 } 

-

1834 

-

1835 makeFiles(d) 

-

1836 stderr = StringIO() 

-

1837 self.cog.setOutput(stderr=stderr) 

-

1838 self.cog.main(['argv0', '-c', '-r', "cog1.txt"]) 

-

1839 self.assertEqual(self.output.getvalue(), "Cogging cog1.txt\n") 

-

1840 self.assertEqual(stderr.getvalue(), "cog1.txt(9): Output has been edited! Delete old checksum to unprotect.\n") 

-

1841 

-

1842 def testDashD(self): 

-

1843 d = { 

-

1844 'test.cog': """\ 

-

1845 --[[[cog cog.outl("Defined fooey as " + fooey) ]]] 

-

1846 --[[[end]]] 

-

1847 """, 

-

1848 

-

1849 'test.kablooey': """\ 

-

1850 --[[[cog cog.outl("Defined fooey as " + fooey) ]]] 

-

1851 Defined fooey as kablooey 

-

1852 --[[[end]]] 

-

1853 """, 

-

1854 

-

1855 'test.einstein': """\ 

-

1856 --[[[cog cog.outl("Defined fooey as " + fooey) ]]] 

-

1857 Defined fooey as e=mc2 

-

1858 --[[[end]]] 

-

1859 """, 

-

1860 } 

-

1861 

-

1862 makeFiles(d) 

-

1863 self.cog.callableMain(['argv0', '-r', '-D', 'fooey=kablooey', 'test.cog']) 

-

1864 self.assertFilesSame('test.cog', 'test.kablooey') 

-

1865 makeFiles(d) 

-

1866 self.cog.callableMain(['argv0', '-r', '-Dfooey=kablooey', 'test.cog']) 

-

1867 self.assertFilesSame('test.cog', 'test.kablooey') 

-

1868 makeFiles(d) 

-

1869 self.cog.callableMain(['argv0', '-r', '-Dfooey=e=mc2', 'test.cog']) 

-

1870 self.assertFilesSame('test.cog', 'test.einstein') 

-

1871 makeFiles(d) 

-

1872 self.cog.callableMain(['argv0', '-r', '-Dbar=quux', '-Dfooey=kablooey', 'test.cog']) 

-

1873 self.assertFilesSame('test.cog', 'test.kablooey') 

-

1874 makeFiles(d) 

-

1875 self.cog.callableMain(['argv0', '-r', '-Dfooey=kablooey', '-Dbar=quux', 'test.cog']) 

-

1876 self.assertFilesSame('test.cog', 'test.kablooey') 

-

1877 makeFiles(d) 

-

1878 self.cog.callableMain(['argv0', '-r', '-Dfooey=gooey', '-Dfooey=kablooey', 'test.cog']) 

-

1879 self.assertFilesSame('test.cog', 'test.kablooey') 

+

1693 } 

+

1694 

+

1695 makeFiles(d) 

+

1696 self.cog.callableMain(['argv0', '-e', 'with.cog']) 

+

1697 output = self.output.getvalue() 

+

1698 self.assertNotIn("Warning", output) 

+

1699 self.newCog() 

+

1700 self.cog.callableMain(['argv0', '-e', 'without.cog']) 

+

1701 output = self.output.getvalue() 

+

1702 self.assertIn("Warning: no cog code found in without.cog", output) 

+

1703 self.newCog() 

+

1704 self.cog.callableMain(['argv0', 'without.cog']) 

+

1705 output = self.output.getvalue() 

+

1706 self.assertNotIn("Warning", output) 

+

1707 

+

1708 def testFileNameProps(self): 

+

1709 d = { 

+

1710 'cog1.txt': """\ 

+

1711 //[[[cog 

+

1712 cog.outl("This is %s in, %s out" % (cog.inFile, cog.outFile)) 

+

1713 //]]] 

+

1714 this is cog1.txt in, cog1.txt out 

+

1715 [[[end]]] 

+

1716 """, 

+

1717 

+

1718 'cog1.out': """\ 

+

1719 //[[[cog 

+

1720 cog.outl("This is %s in, %s out" % (cog.inFile, cog.outFile)) 

+

1721 //]]] 

+

1722 This is cog1.txt in, cog1.txt out 

+

1723 [[[end]]] 

+

1724 """, 

+

1725 

+

1726 'cog1out.out': """\ 

+

1727 //[[[cog 

+

1728 cog.outl("This is %s in, %s out" % (cog.inFile, cog.outFile)) 

+

1729 //]]] 

+

1730 This is cog1.txt in, cog1out.txt out 

+

1731 [[[end]]] 

+

1732 """, 

+

1733 } 

+

1734 

+

1735 makeFiles(d) 

+

1736 self.cog.callableMain(['argv0', '-r', 'cog1.txt']) 

+

1737 self.assertFilesSame('cog1.txt', 'cog1.out') 

+

1738 self.newCog() 

+

1739 self.cog.callableMain(['argv0', '-o', 'cog1out.txt', 'cog1.txt']) 

+

1740 self.assertFilesSame('cog1out.txt', 'cog1out.out') 

+

1741 

+

1742 def testGlobalsDontCrossFiles(self): 

+

1743 # Make sure that global values don't get shared between files. 

+

1744 d = { 

+

1745 'one.cog': """\ 

+

1746 //[[[cog s = "This was set in one.cog" ]]] 

+

1747 //[[[end]]] 

+

1748 //[[[cog cog.outl(s) ]]] 

+

1749 //[[[end]]] 

+

1750 """, 

+

1751 

+

1752 'one.out': """\ 

+

1753 //[[[cog s = "This was set in one.cog" ]]] 

+

1754 //[[[end]]] 

+

1755 //[[[cog cog.outl(s) ]]] 

+

1756 This was set in one.cog 

+

1757 //[[[end]]] 

+

1758 """, 

+

1759 

+

1760 'two.cog': """\ 

+

1761 //[[[cog 

+

1762 try: 

+

1763 cog.outl(s) 

+

1764 except NameError: 

+

1765 cog.outl("s isn't set!") 

+

1766 //]]] 

+

1767 //[[[end]]] 

+

1768 """, 

+

1769 

+

1770 'two.out': """\ 

+

1771 //[[[cog 

+

1772 try: 

+

1773 cog.outl(s) 

+

1774 except NameError: 

+

1775 cog.outl("s isn't set!") 

+

1776 //]]] 

+

1777 s isn't set! 

+

1778 //[[[end]]] 

+

1779 """, 

+

1780 

+

1781 'cogfiles.txt': """\ 

+

1782 # Please run cog 

+

1783 one.cog 

+

1784 

+

1785 two.cog 

+

1786 """ 

+

1787 } 

+

1788 

+

1789 makeFiles(d) 

+

1790 self.cog.callableMain(['argv0', '-r', '@cogfiles.txt']) 

+

1791 self.assertFilesSame('one.cog', 'one.out') 

+

1792 self.assertFilesSame('two.cog', 'two.out') 

+

1793 output = self.output.getvalue() 

+

1794 self.assertIn("(changed)", output) 

+

1795 

+

1796 def testRemoveGeneratedOutput(self): 

+

1797 d = { 

+

1798 'cog1.txt': """\ 

+

1799 //[[[cog 

+

1800 cog.outl("This line was generated.") 

+

1801 //]]] 

+

1802 This line was generated. 

+

1803 //[[[end]]] 

+

1804 This line was not. 

+

1805 """, 

+

1806 

+

1807 'cog1.out': """\ 

+

1808 //[[[cog 

+

1809 cog.outl("This line was generated.") 

+

1810 //]]] 

+

1811 //[[[end]]] 

+

1812 This line was not. 

+

1813 """, 

+

1814 

+

1815 'cog1.out2': """\ 

+

1816 //[[[cog 

+

1817 cog.outl("This line was generated.") 

+

1818 //]]] 

+

1819 This line was generated. 

+

1820 //[[[end]]] 

+

1821 This line was not. 

+

1822 """, 

+

1823 } 

+

1824 

+

1825 makeFiles(d) 

+

1826 # Remove generated output. 

+

1827 self.cog.callableMain(['argv0', '-r', '-x', 'cog1.txt']) 

+

1828 self.assertFilesSame('cog1.txt', 'cog1.out') 

+

1829 self.newCog() 

+

1830 # Regenerate the generated output. 

+

1831 self.cog.callableMain(['argv0', '-r', 'cog1.txt']) 

+

1832 self.assertFilesSame('cog1.txt', 'cog1.out2') 

+

1833 self.newCog() 

+

1834 # Remove the generated output again. 

+

1835 self.cog.callableMain(['argv0', '-r', '-x', 'cog1.txt']) 

+

1836 self.assertFilesSame('cog1.txt', 'cog1.out') 

+

1837 

+

1838 def testMsgCall(self): 

+

1839 infile = """\ 

+

1840 #[[[cog 

+

1841 cog.msg("Hello there!") 

+

1842 #]]] 

+

1843 #[[[end]]] 

+

1844 """ 

+

1845 infile = reindentBlock(infile) 

+

1846 self.assertEqual(self.cog.processString(infile), infile) 

+

1847 output = self.output.getvalue() 

+

1848 self.assertEqual(output, "Message: Hello there!\n") 

+

1849 

+

1850 def testErrorMessageHasNoTraceback(self): 

+

1851 # Test that a Cog error is printed to stderr with no traceback. 

+

1852 

+

1853 d = { 

+

1854 'cog1.txt': """\ 

+

1855 //[[[cog 

+

1856 cog.outl("This line was newly") 

+

1857 cog.outl("generated by cog") 

+

1858 cog.outl("blah blah.") 

+

1859 //]]] 

+

1860 Xhis line was newly 

+

1861 generated by cog 

+

1862 blah blah. 

+

1863 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

+

1864 """, 

+

1865 } 

+

1866 

+

1867 makeFiles(d) 

+

1868 stderr = StringIO() 

+

1869 self.cog.setOutput(stderr=stderr) 

+

1870 self.cog.main(['argv0', '-c', '-r', "cog1.txt"]) 

+

1871 self.assertEqual(self.output.getvalue(), "Cogging cog1.txt\n") 

+

1872 self.assertEqual(stderr.getvalue(), "cog1.txt(9): Output has been edited! Delete old checksum to unprotect.\n") 

+

1873 

+

1874 def testDashD(self): 

+

1875 d = { 

+

1876 'test.cog': """\ 

+

1877 --[[[cog cog.outl("Defined fooey as " + fooey) ]]] 

+

1878 --[[[end]]] 

+

1879 """, 

1880 

-

1881 def testOutputToStdout(self): 

-

1882 d = { 

-

1883 'test.cog': """\ 

-

1884 --[[[cog cog.outl('Hey there!') ]]] 

-

1885 --[[[end]]] 

-

1886 """ 

-

1887 } 

-

1888 

-

1889 makeFiles(d) 

-

1890 stderr = StringIO() 

-

1891 self.cog.setOutput(stderr=stderr) 

-

1892 self.cog.callableMain(['argv0', 'test.cog']) 

-

1893 output = self.output.getvalue() 

-

1894 outerr = stderr.getvalue() 

-

1895 self.assertEqual(output, "--[[[cog cog.outl('Hey there!') ]]]\nHey there!\n--[[[end]]]\n") 

-

1896 self.assertEqual(outerr, "") 

-

1897 

-

1898 def testReadFromStdin(self): 

-

1899 stdin = StringIO("--[[[cog cog.outl('Wow') ]]]\n--[[[end]]]\n") 

-

1900 def restore_stdin(old_stdin): 

-

1901 sys.stdin = old_stdin 

-

1902 self.addCleanup(restore_stdin, sys.stdin) 

-

1903 sys.stdin = stdin 

-

1904 

-

1905 stderr = StringIO() 

-

1906 self.cog.setOutput(stderr=stderr) 

-

1907 self.cog.callableMain(['argv0', '-']) 

-

1908 output = self.output.getvalue() 

-

1909 outerr = stderr.getvalue() 

-

1910 self.assertEqual(output, "--[[[cog cog.outl('Wow') ]]]\nWow\n--[[[end]]]\n") 

-

1911 self.assertEqual(outerr, "") 

+

1881 'test.kablooey': """\ 

+

1882 --[[[cog cog.outl("Defined fooey as " + fooey) ]]] 

+

1883 Defined fooey as kablooey 

+

1884 --[[[end]]] 

+

1885 """, 

+

1886 

+

1887 'test.einstein': """\ 

+

1888 --[[[cog cog.outl("Defined fooey as " + fooey) ]]] 

+

1889 Defined fooey as e=mc2 

+

1890 --[[[end]]] 

+

1891 """, 

+

1892 } 

+

1893 

+

1894 makeFiles(d) 

+

1895 self.cog.callableMain(['argv0', '-r', '-D', 'fooey=kablooey', 'test.cog']) 

+

1896 self.assertFilesSame('test.cog', 'test.kablooey') 

+

1897 makeFiles(d) 

+

1898 self.cog.callableMain(['argv0', '-r', '-Dfooey=kablooey', 'test.cog']) 

+

1899 self.assertFilesSame('test.cog', 'test.kablooey') 

+

1900 makeFiles(d) 

+

1901 self.cog.callableMain(['argv0', '-r', '-Dfooey=e=mc2', 'test.cog']) 

+

1902 self.assertFilesSame('test.cog', 'test.einstein') 

+

1903 makeFiles(d) 

+

1904 self.cog.callableMain(['argv0', '-r', '-Dbar=quux', '-Dfooey=kablooey', 'test.cog']) 

+

1905 self.assertFilesSame('test.cog', 'test.kablooey') 

+

1906 makeFiles(d) 

+

1907 self.cog.callableMain(['argv0', '-r', '-Dfooey=kablooey', '-Dbar=quux', 'test.cog']) 

+

1908 self.assertFilesSame('test.cog', 'test.kablooey') 

+

1909 makeFiles(d) 

+

1910 self.cog.callableMain(['argv0', '-r', '-Dfooey=gooey', '-Dfooey=kablooey', 'test.cog']) 

+

1911 self.assertFilesSame('test.cog', 'test.kablooey') 

1912 

-

1913 def testSuffixOutputLines(self): 

+

1913 def testOutputToStdout(self): 

1914 d = { 

1915 'test.cog': """\ 

-

1916 Hey there. 

-

1917 ;[[[cog cog.outl('a\\nb\\n \\nc') ]]] 

-

1918 ;[[[end]]] 

-

1919 Good bye. 

-

1920 """, 

-

1921 

-

1922 'test.out': """\ 

-

1923 Hey there. 

-

1924 ;[[[cog cog.outl('a\\nb\\n \\nc') ]]] 

-

1925 a (foo) 

-

1926 b (foo) 

-

1927 """ # These three trailing spaces are important. 

-

1928 # The suffix is not applied to completely blank lines. 

-

1929 """ 

-

1930 c (foo) 

-

1931 ;[[[end]]] 

-

1932 Good bye. 

-

1933 """, 

-

1934 } 

-

1935 

-

1936 makeFiles(d) 

-

1937 self.cog.callableMain(['argv0', '-r', '-s', ' (foo)', 'test.cog']) 

-

1938 self.assertFilesSame('test.cog', 'test.out') 

-

1939 

-

1940 def testEmptySuffix(self): 

-

1941 d = { 

-

1942 'test.cog': """\ 

-

1943 ;[[[cog cog.outl('a\\nb\\nc') ]]] 

-

1944 ;[[[end]]] 

-

1945 """, 

-

1946 

-

1947 'test.out': """\ 

-

1948 ;[[[cog cog.outl('a\\nb\\nc') ]]] 

-

1949 a 

-

1950 b 

-

1951 c 

-

1952 ;[[[end]]] 

-

1953 """, 

-

1954 } 

-

1955 

-

1956 makeFiles(d) 

-

1957 self.cog.callableMain(['argv0', '-r', '-s', '', 'test.cog']) 

-

1958 self.assertFilesSame('test.cog', 'test.out') 

-

1959 

-

1960 def testHellishSuffix(self): 

-

1961 d = { 

-

1962 'test.cog': """\ 

-

1963 ;[[[cog cog.outl('a\\n\\nb') ]]] 

-

1964 """, 

-

1965 

-

1966 'test.out': """\ 

-

1967 ;[[[cog cog.outl('a\\n\\nb') ]]] 

-

1968 a /\\n*+([)]>< 

-

1969 

-

1970 b /\\n*+([)]>< 

-

1971 """, 

-

1972 } 

-

1973 

-

1974 makeFiles(d) 

-

1975 self.cog.callableMain(['argv0', '-z', '-r', '-s', r' /\n*+([)]><', 'test.cog']) 

-

1976 self.assertFilesSame('test.cog', 'test.out') 

-

1977 

-

1978 def testPrologue(self): 

-

1979 d = { 

-

1980 'test.cog': """\ 

-

1981 Some text. 

-

1982 //[[[cog cog.outl(str(math.sqrt(2))[:12])]]] 

-

1983 //[[[end]]] 

-

1984 epilogue. 

+

1916 --[[[cog cog.outl('Hey there!') ]]] 

+

1917 --[[[end]]] 

+

1918 """ 

+

1919 } 

+

1920 

+

1921 makeFiles(d) 

+

1922 stderr = StringIO() 

+

1923 self.cog.setOutput(stderr=stderr) 

+

1924 self.cog.callableMain(['argv0', 'test.cog']) 

+

1925 output = self.output.getvalue() 

+

1926 outerr = stderr.getvalue() 

+

1927 self.assertEqual(output, "--[[[cog cog.outl('Hey there!') ]]]\nHey there!\n--[[[end]]]\n") 

+

1928 self.assertEqual(outerr, "") 

+

1929 

+

1930 def testReadFromStdin(self): 

+

1931 stdin = StringIO("--[[[cog cog.outl('Wow') ]]]\n--[[[end]]]\n") 

+

1932 def restore_stdin(old_stdin): 

+

1933 sys.stdin = old_stdin 

+

1934 self.addCleanup(restore_stdin, sys.stdin) 

+

1935 sys.stdin = stdin 

+

1936 

+

1937 stderr = StringIO() 

+

1938 self.cog.setOutput(stderr=stderr) 

+

1939 self.cog.callableMain(['argv0', '-']) 

+

1940 output = self.output.getvalue() 

+

1941 outerr = stderr.getvalue() 

+

1942 self.assertEqual(output, "--[[[cog cog.outl('Wow') ]]]\nWow\n--[[[end]]]\n") 

+

1943 self.assertEqual(outerr, "") 

+

1944 

+

1945 def testSuffixOutputLines(self): 

+

1946 d = { 

+

1947 'test.cog': """\ 

+

1948 Hey there. 

+

1949 ;[[[cog cog.outl('a\\nb\\n \\nc') ]]] 

+

1950 ;[[[end]]] 

+

1951 Good bye. 

+

1952 """, 

+

1953 

+

1954 'test.out': """\ 

+

1955 Hey there. 

+

1956 ;[[[cog cog.outl('a\\nb\\n \\nc') ]]] 

+

1957 a (foo) 

+

1958 b (foo) 

+

1959 """ # These three trailing spaces are important. 

+

1960 # The suffix is not applied to completely blank lines. 

+

1961 """ 

+

1962 c (foo) 

+

1963 ;[[[end]]] 

+

1964 Good bye. 

+

1965 """, 

+

1966 } 

+

1967 

+

1968 makeFiles(d) 

+

1969 self.cog.callableMain(['argv0', '-r', '-s', ' (foo)', 'test.cog']) 

+

1970 self.assertFilesSame('test.cog', 'test.out') 

+

1971 

+

1972 def testEmptySuffix(self): 

+

1973 d = { 

+

1974 'test.cog': """\ 

+

1975 ;[[[cog cog.outl('a\\nb\\nc') ]]] 

+

1976 ;[[[end]]] 

+

1977 """, 

+

1978 

+

1979 'test.out': """\ 

+

1980 ;[[[cog cog.outl('a\\nb\\nc') ]]] 

+

1981 a 

+

1982 b 

+

1983 c 

+

1984 ;[[[end]]] 

1985 """, 

-

1986 

-

1987 'test.out': """\ 

-

1988 Some text. 

-

1989 //[[[cog cog.outl(str(math.sqrt(2))[:12])]]] 

-

1990 1.4142135623 

-

1991 //[[[end]]] 

-

1992 epilogue. 

-

1993 """, 

-

1994 } 

-

1995 

-

1996 makeFiles(d) 

-

1997 self.cog.callableMain(['argv0', '-r', '-p', 'import math', 'test.cog']) 

-

1998 self.assertFilesSame('test.cog', 'test.out') 

-

1999 

-

2000 def testThreads(self): 

-

2001 # Test that the implicitly imported cog module is actually different for 

-

2002 # different threads. 

-

2003 numthreads = 20 

-

2004 

-

2005 d = {} 

-

2006 for i in range(numthreads): 

-

2007 d['f{}.cog'.format(i)] = ( 

-

2008 "x\n" * i + 

-

2009 "[[[cog\n" + 

-

2010 "assert cog.firstLineNum == int(FIRST) == {}\n".format(i+1) + 

-

2011 "]]]\n" + 

-

2012 "[[[end]]]\n" 

-

2013 ) 

-

2014 makeFiles(d) 

-

2015 

-

2016 results = [] 

-

2017 

-

2018 def thread_main(num): 

-

2019 try: 

-

2020 ret = Cog().main( 

-

2021 ['cog.py', '-r', '-D', 'FIRST={}'.format(num+1), 'f{}.cog'.format(num)] 

-

2022 ) 

-

2023 assert ret == 0 

-

2024 except Exception as exc: # pragma: no cover (only happens on test failure) 

-

2025 results.append(exc) 

-

2026 else: 

-

2027 results.append(None) 

-

2028 

-

2029 ts = [threading.Thread(target=thread_main, args=(i,)) for i in range(numthreads)] 

-

2030 for t in ts: 

-

2031 t.start() 

-

2032 for t in ts: 

-

2033 t.join() 

-

2034 assert results == [None] * numthreads 

-

2035 

+

1986 } 

+

1987 

+

1988 makeFiles(d) 

+

1989 self.cog.callableMain(['argv0', '-r', '-s', '', 'test.cog']) 

+

1990 self.assertFilesSame('test.cog', 'test.out') 

+

1991 

+

1992 def testHellishSuffix(self): 

+

1993 d = { 

+

1994 'test.cog': """\ 

+

1995 ;[[[cog cog.outl('a\\n\\nb') ]]] 

+

1996 """, 

+

1997 

+

1998 'test.out': """\ 

+

1999 ;[[[cog cog.outl('a\\n\\nb') ]]] 

+

2000 a /\\n*+([)]>< 

+

2001 

+

2002 b /\\n*+([)]>< 

+

2003 """, 

+

2004 } 

+

2005 

+

2006 makeFiles(d) 

+

2007 self.cog.callableMain(['argv0', '-z', '-r', '-s', r' /\n*+([)]><', 'test.cog']) 

+

2008 self.assertFilesSame('test.cog', 'test.out') 

+

2009 

+

2010 def testPrologue(self): 

+

2011 d = { 

+

2012 'test.cog': """\ 

+

2013 Some text. 

+

2014 //[[[cog cog.outl(str(math.sqrt(2))[:12])]]] 

+

2015 //[[[end]]] 

+

2016 epilogue. 

+

2017 """, 

+

2018 

+

2019 'test.out': """\ 

+

2020 Some text. 

+

2021 //[[[cog cog.outl(str(math.sqrt(2))[:12])]]] 

+

2022 1.4142135623 

+

2023 //[[[end]]] 

+

2024 epilogue. 

+

2025 """, 

+

2026 } 

+

2027 

+

2028 makeFiles(d) 

+

2029 self.cog.callableMain(['argv0', '-r', '-p', 'import math', 'test.cog']) 

+

2030 self.assertFilesSame('test.cog', 'test.out') 

+

2031 

+

2032 def testThreads(self): 

+

2033 # Test that the implicitly imported cog module is actually different for 

+

2034 # different threads. 

+

2035 numthreads = 20 

2036 

-

2037class WritabilityTests(TestCaseWithTempDir): 

-

2038 

-

2039 d = { 

-

2040 'test.cog': """\ 

-

2041 //[[[cog 

-

2042 for fn in ['DoSomething', 'DoAnotherThing', 'DoLastThing']: 

-

2043 cog.outl("void %s();" % fn) 

-

2044 //]]] 

-

2045 //[[[end]]] 

-

2046 """, 

+

2037 d = {} 

+

2038 for i in range(numthreads): 

+

2039 d['f{}.cog'.format(i)] = ( 

+

2040 "x\n" * i + 

+

2041 "[[[cog\n" + 

+

2042 "assert cog.firstLineNum == int(FIRST) == {}\n".format(i+1) + 

+

2043 "]]]\n" + 

+

2044 "[[[end]]]\n" 

+

2045 ) 

+

2046 makeFiles(d) 

2047 

-

2048 'test.out': """\ 

-

2049 //[[[cog 

-

2050 for fn in ['DoSomething', 'DoAnotherThing', 'DoLastThing']: 

-

2051 cog.outl("void %s();" % fn) 

-

2052 //]]] 

-

2053 void DoSomething(); 

-

2054 void DoAnotherThing(); 

-

2055 void DoLastThing(); 

-

2056 //[[[end]]] 

-

2057 """, 

-

2058 } 

-

2059 

-

2060 if os.name == 'nt': #pragma: no cover 

-

2061 # for Windows 

-

2062 cmd_w_args = 'attrib -R %s' 

-

2063 cmd_w_asterisk = 'attrib -R *' 

-

2064 else: #pragma: no cover 

-

2065 # for unix-like 

-

2066 cmd_w_args = 'chmod +w %s' 

-

2067 cmd_w_asterisk = 'chmod +w *' 

+

2048 results = [] 

+

2049 

+

2050 def thread_main(num): 

+

2051 try: 

+

2052 ret = Cog().main( 

+

2053 ['cog.py', '-r', '-D', 'FIRST={}'.format(num+1), 'f{}.cog'.format(num)] 

+

2054 ) 

+

2055 assert ret == 0 

+

2056 except Exception as exc: # pragma: no cover (only happens on test failure) 

+

2057 results.append(exc) 

+

2058 else: 

+

2059 results.append(None) 

+

2060 

+

2061 ts = [threading.Thread(target=thread_main, args=(i,)) for i in range(numthreads)] 

+

2062 for t in ts: 

+

2063 t.start() 

+

2064 for t in ts: 

+

2065 t.join() 

+

2066 assert results == [None] * numthreads 

+

2067 

2068 

-

2069 def setUp(self): 

-

2070 super(WritabilityTests, self).setUp() 

-

2071 makeFiles(self.d) 

-

2072 self.testcog = os.path.join(self.tempdir, 'test.cog') 

-

2073 os.chmod(self.testcog, stat.S_IREAD) # Make the file readonly. 

-

2074 assert not os.access(self.testcog, os.W_OK) 

-

2075 

-

2076 def tearDown(self): 

-

2077 os.chmod(self.testcog, stat.S_IWRITE) # Make the file writable again. 

-

2078 super(WritabilityTests, self).tearDown() 

+

2069class WritabilityTests(TestCaseWithTempDir): 

+

2070 

+

2071 d = { 

+

2072 'test.cog': """\ 

+

2073 //[[[cog 

+

2074 for fn in ['DoSomething', 'DoAnotherThing', 'DoLastThing']: 

+

2075 cog.outl("void %s();" % fn) 

+

2076 //]]] 

+

2077 //[[[end]]] 

+

2078 """, 

2079 

-

2080 def testReadonlyNoCommand(self): 

-

2081 with self.assertRaisesRegex(CogError, "^Can't overwrite test.cog$"): 

-

2082 self.cog.callableMain(['argv0', '-r', 'test.cog']) 

-

2083 assert not os.access(self.testcog, os.W_OK) 

-

2084 

-

2085 def testReadonlyWithCommand(self): 

-

2086 self.cog.callableMain(['argv0', '-r', '-w', self.cmd_w_args, 'test.cog']) 

-

2087 self.assertFilesSame('test.cog', 'test.out') 

-

2088 assert os.access(self.testcog, os.W_OK) 

-

2089 

-

2090 def testReadonlyWithCommandWithNoSlot(self): 

-

2091 self.cog.callableMain(['argv0', '-r', '-w', self.cmd_w_asterisk, 'test.cog']) 

-

2092 self.assertFilesSame('test.cog', 'test.out') 

-

2093 assert os.access(self.testcog, os.W_OK) 

-

2094 

-

2095 def testReadonlyWithIneffectualCommand(self): 

-

2096 with self.assertRaisesRegex(CogError, "^Couldn't make test.cog writable$"): 

-

2097 self.cog.callableMain(['argv0', '-r', '-w', 'echo %s', 'test.cog']) 

-

2098 assert not os.access(self.testcog, os.W_OK) 

-

2099 

+

2080 'test.out': """\ 

+

2081 //[[[cog 

+

2082 for fn in ['DoSomething', 'DoAnotherThing', 'DoLastThing']: 

+

2083 cog.outl("void %s();" % fn) 

+

2084 //]]] 

+

2085 void DoSomething(); 

+

2086 void DoAnotherThing(); 

+

2087 void DoLastThing(); 

+

2088 //[[[end]]] 

+

2089 """, 

+

2090 } 

+

2091 

+

2092 if os.name == 'nt': #pragma: no cover 

+

2093 # for Windows 

+

2094 cmd_w_args = 'attrib -R %s' 

+

2095 cmd_w_asterisk = 'attrib -R *' 

+

2096 else: #pragma: no cover 

+

2097 # for unix-like 

+

2098 cmd_w_args = 'chmod +w %s' 

+

2099 cmd_w_asterisk = 'chmod +w *' 

2100 

-

2101class ChecksumTests(TestCaseWithTempDir): 

-

2102 

-

2103 def testCreateChecksumOutput(self): 

-

2104 d = { 

-

2105 'cog1.txt': """\ 

-

2106 //[[[cog 

-

2107 cog.outl("This line was generated.") 

-

2108 //]]] 

-

2109 This line was generated. 

-

2110 //[[[end]]] 

-

2111 This line was not. 

-

2112 """, 

-

2113 

-

2114 'cog1.out': """\ 

-

2115 //[[[cog 

-

2116 cog.outl("This line was generated.") 

-

2117 //]]] 

-

2118 This line was generated. 

-

2119 //[[[end]]] (checksum: 8adb13fb59b996a1c7f0065ea9f3d893) 

-

2120 This line was not. 

-

2121 """, 

-

2122 } 

-

2123 

-

2124 makeFiles(d) 

-

2125 self.cog.callableMain(['argv0', '-r', '-c', 'cog1.txt']) 

-

2126 self.assertFilesSame('cog1.txt', 'cog1.out') 

-

2127 

-

2128 def testCheckChecksumOutput(self): 

-

2129 d = { 

-

2130 'cog1.txt': """\ 

-

2131 //[[[cog 

-

2132 cog.outl("This line was newly") 

-

2133 cog.outl("generated by cog") 

-

2134 cog.outl("blah blah.") 

-

2135 //]]] 

-

2136 This line was generated. 

-

2137 //[[[end]]] (checksum: 8adb13fb59b996a1c7f0065ea9f3d893) 

-

2138 """, 

-

2139 

-

2140 'cog1.out': """\ 

-

2141 //[[[cog 

-

2142 cog.outl("This line was newly") 

-

2143 cog.outl("generated by cog") 

-

2144 cog.outl("blah blah.") 

-

2145 //]]] 

-

2146 This line was newly 

-

2147 generated by cog 

-

2148 blah blah. 

-

2149 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

-

2150 """, 

-

2151 } 

-

2152 

-

2153 makeFiles(d) 

-

2154 self.cog.callableMain(['argv0', '-r', '-c', 'cog1.txt']) 

-

2155 self.assertFilesSame('cog1.txt', 'cog1.out') 

-

2156 

-

2157 def testRemoveChecksumOutput(self): 

-

2158 d = { 

-

2159 'cog1.txt': """\ 

-

2160 //[[[cog 

-

2161 cog.outl("This line was newly") 

-

2162 cog.outl("generated by cog") 

-

2163 cog.outl("blah blah.") 

-

2164 //]]] 

-

2165 This line was generated. 

-

2166 //[[[end]]] (checksum: 8adb13fb59b996a1c7f0065ea9f3d893) fooey 

-

2167 """, 

-

2168 

-

2169 'cog1.out': """\ 

-

2170 //[[[cog 

-

2171 cog.outl("This line was newly") 

-

2172 cog.outl("generated by cog") 

-

2173 cog.outl("blah blah.") 

-

2174 //]]] 

-

2175 This line was newly 

-

2176 generated by cog 

-

2177 blah blah. 

-

2178 //[[[end]]] fooey 

-

2179 """, 

-

2180 } 

-

2181 

-

2182 makeFiles(d) 

-

2183 self.cog.callableMain(['argv0', '-r', 'cog1.txt']) 

-

2184 self.assertFilesSame('cog1.txt', 'cog1.out') 

-

2185 

-

2186 def testTamperedChecksumOutput(self): 

-

2187 d = { 

-

2188 'cog1.txt': """\ 

-

2189 //[[[cog 

-

2190 cog.outl("This line was newly") 

-

2191 cog.outl("generated by cog") 

-

2192 cog.outl("blah blah.") 

-

2193 //]]] 

-

2194 Xhis line was newly 

-

2195 generated by cog 

-

2196 blah blah. 

-

2197 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

-

2198 """, 

-

2199 

-

2200 'cog2.txt': """\ 

-

2201 //[[[cog 

-

2202 cog.outl("This line was newly") 

-

2203 cog.outl("generated by cog") 

-

2204 cog.outl("blah blah.") 

-

2205 //]]] 

-

2206 This line was newly 

-

2207 generated by cog 

-

2208 blah blah! 

-

2209 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

-

2210 """, 

-

2211 

-

2212 'cog3.txt': """\ 

-

2213 //[[[cog 

-

2214 cog.outl("This line was newly") 

-

2215 cog.outl("generated by cog") 

-

2216 cog.outl("blah blah.") 

-

2217 //]]] 

-

2218 

-

2219 This line was newly 

-

2220 generated by cog 

-

2221 blah blah. 

-

2222 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

-

2223 """, 

-

2224 

-

2225 'cog4.txt': """\ 

-

2226 //[[[cog 

-

2227 cog.outl("This line was newly") 

-

2228 cog.outl("generated by cog") 

-

2229 cog.outl("blah blah.") 

-

2230 //]]] 

-

2231 This line was newly 

-

2232 generated by cog 

-

2233 blah blah.. 

-

2234 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

-

2235 """, 

-

2236 

-

2237 'cog5.txt': """\ 

-

2238 //[[[cog 

-

2239 cog.outl("This line was newly") 

-

2240 cog.outl("generated by cog") 

-

2241 cog.outl("blah blah.") 

-

2242 //]]] 

-

2243 This line was newly 

-

2244 generated by cog 

-

2245 blah blah. 

-

2246 extra 

-

2247 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

-

2248 """, 

-

2249 

-

2250 'cog6.txt': """\ 

-

2251 //[[[cog 

-

2252 cog.outl("This line was newly") 

-

2253 cog.outl("generated by cog") 

-

2254 cog.outl("blah blah.") 

-

2255 //]]] 

-

2256 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

-

2257 """, 

-

2258 } 

-

2259 

-

2260 makeFiles(d) 

-

2261 with self.assertRaisesRegex(CogError, 

-

2262 r"^cog1.txt\(9\): Output has been edited! Delete old checksum to unprotect.$"): 

-

2263 self.cog.callableMain(['argv0', '-c', "cog1.txt"]) 

-

2264 with self.assertRaisesRegex(CogError, 

-

2265 r"^cog2.txt\(9\): Output has been edited! Delete old checksum to unprotect.$"): 

-

2266 self.cog.callableMain(['argv0', '-c', "cog2.txt"]) 

-

2267 with self.assertRaisesRegex(CogError, 

-

2268 r"^cog3.txt\(10\): Output has been edited! Delete old checksum to unprotect.$"): 

-

2269 self.cog.callableMain(['argv0', '-c', "cog3.txt"]) 

-

2270 with self.assertRaisesRegex(CogError, 

-

2271 r"^cog4.txt\(9\): Output has been edited! Delete old checksum to unprotect.$"): 

-

2272 self.cog.callableMain(['argv0', '-c', "cog4.txt"]) 

-

2273 with self.assertRaisesRegex(CogError, 

-

2274 r"^cog5.txt\(10\): Output has been edited! Delete old checksum to unprotect.$"): 

-

2275 self.cog.callableMain(['argv0', '-c', "cog5.txt"]) 

-

2276 with self.assertRaisesRegex(CogError, 

-

2277 r"^cog6.txt\(6\): Output has been edited! Delete old checksum to unprotect.$"): 

-

2278 self.cog.callableMain(['argv0', '-c', "cog6.txt"]) 

-

2279 

-

2280 def testArgvIsntModified(self): 

-

2281 argv = ['argv0', '-v'] 

-

2282 orig_argv = argv[:] 

-

2283 self.cog.callableMain(argv) 

-

2284 self.assertEqual(argv, orig_argv) 

-

2285 

-

2286 

-

2287class CustomMarkerTests(TestCaseWithTempDir): 

-

2288 

-

2289 def testCustomerMarkers(self): 

-

2290 d = { 

-

2291 'test.cog': """\ 

-

2292 //{{ 

-

2293 cog.outl("void %s();" % "MyFunction") 

-

2294 //}} 

-

2295 //{{end}} 

-

2296 """, 

-

2297 

-

2298 'test.out': """\ 

-

2299 //{{ 

-

2300 cog.outl("void %s();" % "MyFunction") 

-

2301 //}} 

-

2302 void MyFunction(); 

-

2303 //{{end}} 

-

2304 """, 

-

2305 } 

-

2306 

-

2307 makeFiles(d) 

-

2308 self.cog.callableMain([ 

-

2309 'argv0', '-r', 

-

2310 '--markers={{ }} {{end}}', 

-

2311 'test.cog' 

-

2312 ]) 

-

2313 self.assertFilesSame('test.cog', 'test.out') 

-

2314 

-

2315 def testTrulyWackyMarkers(self): 

-

2316 # Make sure the markers are properly re-escaped. 

-

2317 d = { 

-

2318 'test.cog': """\ 

-

2319 //**( 

-

2320 cog.outl("void %s();" % "MyFunction") 

-

2321 //**) 

-

2322 //**(end)** 

-

2323 """, 

-

2324 

-

2325 'test.out': """\ 

-

2326 //**( 

-

2327 cog.outl("void %s();" % "MyFunction") 

-

2328 //**) 

-

2329 void MyFunction(); 

-

2330 //**(end)** 

-

2331 """, 

-

2332 } 

-

2333 

-

2334 makeFiles(d) 

-

2335 self.cog.callableMain([ 

-

2336 'argv0', '-r', 

-

2337 '--markers=**( **) **(end)**', 

-

2338 'test.cog' 

-

2339 ]) 

-

2340 self.assertFilesSame('test.cog', 'test.out') 

-

2341 

-

2342 def testChangeJustOneMarker(self): 

-

2343 d = { 

-

2344 'test.cog': """\ 

-

2345 //**( 

-

2346 cog.outl("void %s();" % "MyFunction") 

-

2347 //]]] 

-

2348 //[[[end]]] 

-

2349 """, 

-

2350 

-

2351 'test.out': """\ 

-

2352 //**( 

-

2353 cog.outl("void %s();" % "MyFunction") 

-

2354 //]]] 

-

2355 void MyFunction(); 

-

2356 //[[[end]]] 

-

2357 """, 

-

2358 } 

-

2359 

-

2360 makeFiles(d) 

-

2361 self.cog.callableMain([ 

-

2362 'argv0', '-r', 

-

2363 '--markers=**( ]]] [[[end]]]', 

-

2364 'test.cog' 

-

2365 ]) 

-

2366 self.assertFilesSame('test.cog', 'test.out') 

-

2367 

-

2368 

-

2369class BlakeTests(TestCaseWithTempDir): 

-

2370 

-

2371 # Blake Winton's contributions. 

-

2372 def testDeleteCode(self): 

-

2373 # -o sets the output file. 

-

2374 d = { 

-

2375 'test.cog': """\ 

-

2376 // This is my C++ file. 

-

2377 //[[[cog 

-

2378 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

-

2379 for fn in fnames: 

-

2380 cog.outl("void %s();" % fn) 

-

2381 //]]] 

-

2382 Some Sample Code Here 

-

2383 //[[[end]]]Data Data 

-

2384 And Some More 

-

2385 """, 

-

2386 

-

2387 'test.out': """\ 

-

2388 // This is my C++ file. 

-

2389 void DoSomething(); 

-

2390 void DoAnotherThing(); 

-

2391 void DoLastThing(); 

-

2392 And Some More 

-

2393 """, 

-

2394 } 

-

2395 

-

2396 makeFiles(d) 

-

2397 self.cog.callableMain(['argv0', '-d', '-o', 'test.cogged', 'test.cog']) 

-

2398 self.assertFilesSame('test.cogged', 'test.out') 

+

2101 def setUp(self): 

+

2102 super(WritabilityTests, self).setUp() 

+

2103 makeFiles(self.d) 

+

2104 self.testcog = os.path.join(self.tempdir, 'test.cog') 

+

2105 os.chmod(self.testcog, stat.S_IREAD) # Make the file readonly. 

+

2106 assert not os.access(self.testcog, os.W_OK) 

+

2107 

+

2108 def tearDown(self): 

+

2109 os.chmod(self.testcog, stat.S_IWRITE) # Make the file writable again. 

+

2110 super(WritabilityTests, self).tearDown() 

+

2111 

+

2112 def testReadonlyNoCommand(self): 

+

2113 with self.assertRaisesRegex(CogError, "^Can't overwrite test.cog$"): 

+

2114 self.cog.callableMain(['argv0', '-r', 'test.cog']) 

+

2115 assert not os.access(self.testcog, os.W_OK) 

+

2116 

+

2117 def testReadonlyWithCommand(self): 

+

2118 self.cog.callableMain(['argv0', '-r', '-w', self.cmd_w_args, 'test.cog']) 

+

2119 self.assertFilesSame('test.cog', 'test.out') 

+

2120 assert os.access(self.testcog, os.W_OK) 

+

2121 

+

2122 def testReadonlyWithCommandWithNoSlot(self): 

+

2123 self.cog.callableMain(['argv0', '-r', '-w', self.cmd_w_asterisk, 'test.cog']) 

+

2124 self.assertFilesSame('test.cog', 'test.out') 

+

2125 assert os.access(self.testcog, os.W_OK) 

+

2126 

+

2127 def testReadonlyWithIneffectualCommand(self): 

+

2128 with self.assertRaisesRegex(CogError, "^Couldn't make test.cog writable$"): 

+

2129 self.cog.callableMain(['argv0', '-r', '-w', 'echo %s', 'test.cog']) 

+

2130 assert not os.access(self.testcog, os.W_OK) 

+

2131 

+

2132 

+

2133class ChecksumTests(TestCaseWithTempDir): 

+

2134 

+

2135 def testCreateChecksumOutput(self): 

+

2136 d = { 

+

2137 'cog1.txt': """\ 

+

2138 //[[[cog 

+

2139 cog.outl("This line was generated.") 

+

2140 //]]] 

+

2141 This line was generated. 

+

2142 //[[[end]]] 

+

2143 This line was not. 

+

2144 """, 

+

2145 

+

2146 'cog1.out': """\ 

+

2147 //[[[cog 

+

2148 cog.outl("This line was generated.") 

+

2149 //]]] 

+

2150 This line was generated. 

+

2151 //[[[end]]] (checksum: 8adb13fb59b996a1c7f0065ea9f3d893) 

+

2152 This line was not. 

+

2153 """, 

+

2154 } 

+

2155 

+

2156 makeFiles(d) 

+

2157 self.cog.callableMain(['argv0', '-r', '-c', 'cog1.txt']) 

+

2158 self.assertFilesSame('cog1.txt', 'cog1.out') 

+

2159 

+

2160 def testCheckChecksumOutput(self): 

+

2161 d = { 

+

2162 'cog1.txt': """\ 

+

2163 //[[[cog 

+

2164 cog.outl("This line was newly") 

+

2165 cog.outl("generated by cog") 

+

2166 cog.outl("blah blah.") 

+

2167 //]]] 

+

2168 This line was generated. 

+

2169 //[[[end]]] (checksum: 8adb13fb59b996a1c7f0065ea9f3d893) 

+

2170 """, 

+

2171 

+

2172 'cog1.out': """\ 

+

2173 //[[[cog 

+

2174 cog.outl("This line was newly") 

+

2175 cog.outl("generated by cog") 

+

2176 cog.outl("blah blah.") 

+

2177 //]]] 

+

2178 This line was newly 

+

2179 generated by cog 

+

2180 blah blah. 

+

2181 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

+

2182 """, 

+

2183 } 

+

2184 

+

2185 makeFiles(d) 

+

2186 self.cog.callableMain(['argv0', '-r', '-c', 'cog1.txt']) 

+

2187 self.assertFilesSame('cog1.txt', 'cog1.out') 

+

2188 

+

2189 def testRemoveChecksumOutput(self): 

+

2190 d = { 

+

2191 'cog1.txt': """\ 

+

2192 //[[[cog 

+

2193 cog.outl("This line was newly") 

+

2194 cog.outl("generated by cog") 

+

2195 cog.outl("blah blah.") 

+

2196 //]]] 

+

2197 This line was generated. 

+

2198 //[[[end]]] (checksum: 8adb13fb59b996a1c7f0065ea9f3d893) fooey 

+

2199 """, 

+

2200 

+

2201 'cog1.out': """\ 

+

2202 //[[[cog 

+

2203 cog.outl("This line was newly") 

+

2204 cog.outl("generated by cog") 

+

2205 cog.outl("blah blah.") 

+

2206 //]]] 

+

2207 This line was newly 

+

2208 generated by cog 

+

2209 blah blah. 

+

2210 //[[[end]]] fooey 

+

2211 """, 

+

2212 } 

+

2213 

+

2214 makeFiles(d) 

+

2215 self.cog.callableMain(['argv0', '-r', 'cog1.txt']) 

+

2216 self.assertFilesSame('cog1.txt', 'cog1.out') 

+

2217 

+

2218 def testTamperedChecksumOutput(self): 

+

2219 d = { 

+

2220 'cog1.txt': """\ 

+

2221 //[[[cog 

+

2222 cog.outl("This line was newly") 

+

2223 cog.outl("generated by cog") 

+

2224 cog.outl("blah blah.") 

+

2225 //]]] 

+

2226 Xhis line was newly 

+

2227 generated by cog 

+

2228 blah blah. 

+

2229 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

+

2230 """, 

+

2231 

+

2232 'cog2.txt': """\ 

+

2233 //[[[cog 

+

2234 cog.outl("This line was newly") 

+

2235 cog.outl("generated by cog") 

+

2236 cog.outl("blah blah.") 

+

2237 //]]] 

+

2238 This line was newly 

+

2239 generated by cog 

+

2240 blah blah! 

+

2241 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

+

2242 """, 

+

2243 

+

2244 'cog3.txt': """\ 

+

2245 //[[[cog 

+

2246 cog.outl("This line was newly") 

+

2247 cog.outl("generated by cog") 

+

2248 cog.outl("blah blah.") 

+

2249 //]]] 

+

2250 

+

2251 This line was newly 

+

2252 generated by cog 

+

2253 blah blah. 

+

2254 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

+

2255 """, 

+

2256 

+

2257 'cog4.txt': """\ 

+

2258 //[[[cog 

+

2259 cog.outl("This line was newly") 

+

2260 cog.outl("generated by cog") 

+

2261 cog.outl("blah blah.") 

+

2262 //]]] 

+

2263 This line was newly 

+

2264 generated by cog 

+

2265 blah blah.. 

+

2266 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

+

2267 """, 

+

2268 

+

2269 'cog5.txt': """\ 

+

2270 //[[[cog 

+

2271 cog.outl("This line was newly") 

+

2272 cog.outl("generated by cog") 

+

2273 cog.outl("blah blah.") 

+

2274 //]]] 

+

2275 This line was newly 

+

2276 generated by cog 

+

2277 blah blah. 

+

2278 extra 

+

2279 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

+

2280 """, 

+

2281 

+

2282 'cog6.txt': """\ 

+

2283 //[[[cog 

+

2284 cog.outl("This line was newly") 

+

2285 cog.outl("generated by cog") 

+

2286 cog.outl("blah blah.") 

+

2287 //]]] 

+

2288 //[[[end]]] (checksum: a8540982e5ad6b95c9e9a184b26f4346) 

+

2289 """, 

+

2290 } 

+

2291 

+

2292 makeFiles(d) 

+

2293 with self.assertRaisesRegex(CogError, 

+

2294 r"^cog1.txt\(9\): Output has been edited! Delete old checksum to unprotect.$"): 

+

2295 self.cog.callableMain(['argv0', '-c', "cog1.txt"]) 

+

2296 with self.assertRaisesRegex(CogError, 

+

2297 r"^cog2.txt\(9\): Output has been edited! Delete old checksum to unprotect.$"): 

+

2298 self.cog.callableMain(['argv0', '-c', "cog2.txt"]) 

+

2299 with self.assertRaisesRegex(CogError, 

+

2300 r"^cog3.txt\(10\): Output has been edited! Delete old checksum to unprotect.$"): 

+

2301 self.cog.callableMain(['argv0', '-c', "cog3.txt"]) 

+

2302 with self.assertRaisesRegex(CogError, 

+

2303 r"^cog4.txt\(9\): Output has been edited! Delete old checksum to unprotect.$"): 

+

2304 self.cog.callableMain(['argv0', '-c', "cog4.txt"]) 

+

2305 with self.assertRaisesRegex(CogError, 

+

2306 r"^cog5.txt\(10\): Output has been edited! Delete old checksum to unprotect.$"): 

+

2307 self.cog.callableMain(['argv0', '-c', "cog5.txt"]) 

+

2308 with self.assertRaisesRegex(CogError, 

+

2309 r"^cog6.txt\(6\): Output has been edited! Delete old checksum to unprotect.$"): 

+

2310 self.cog.callableMain(['argv0', '-c', "cog6.txt"]) 

+

2311 

+

2312 def testArgvIsntModified(self): 

+

2313 argv = ['argv0', '-v'] 

+

2314 orig_argv = argv[:] 

+

2315 self.cog.callableMain(argv) 

+

2316 self.assertEqual(argv, orig_argv) 

+

2317 

+

2318 

+

2319class CustomMarkerTests(TestCaseWithTempDir): 

+

2320 

+

2321 def testCustomerMarkers(self): 

+

2322 d = { 

+

2323 'test.cog': """\ 

+

2324 //{{ 

+

2325 cog.outl("void %s();" % "MyFunction") 

+

2326 //}} 

+

2327 //{{end}} 

+

2328 """, 

+

2329 

+

2330 'test.out': """\ 

+

2331 //{{ 

+

2332 cog.outl("void %s();" % "MyFunction") 

+

2333 //}} 

+

2334 void MyFunction(); 

+

2335 //{{end}} 

+

2336 """, 

+

2337 } 

+

2338 

+

2339 makeFiles(d) 

+

2340 self.cog.callableMain([ 

+

2341 'argv0', '-r', 

+

2342 '--markers={{ }} {{end}}', 

+

2343 'test.cog' 

+

2344 ]) 

+

2345 self.assertFilesSame('test.cog', 'test.out') 

+

2346 

+

2347 def testTrulyWackyMarkers(self): 

+

2348 # Make sure the markers are properly re-escaped. 

+

2349 d = { 

+

2350 'test.cog': """\ 

+

2351 //**( 

+

2352 cog.outl("void %s();" % "MyFunction") 

+

2353 //**) 

+

2354 //**(end)** 

+

2355 """, 

+

2356 

+

2357 'test.out': """\ 

+

2358 //**( 

+

2359 cog.outl("void %s();" % "MyFunction") 

+

2360 //**) 

+

2361 void MyFunction(); 

+

2362 //**(end)** 

+

2363 """, 

+

2364 } 

+

2365 

+

2366 makeFiles(d) 

+

2367 self.cog.callableMain([ 

+

2368 'argv0', '-r', 

+

2369 '--markers=**( **) **(end)**', 

+

2370 'test.cog' 

+

2371 ]) 

+

2372 self.assertFilesSame('test.cog', 'test.out') 

+

2373 

+

2374 def testChangeJustOneMarker(self): 

+

2375 d = { 

+

2376 'test.cog': """\ 

+

2377 //**( 

+

2378 cog.outl("void %s();" % "MyFunction") 

+

2379 //]]] 

+

2380 //[[[end]]] 

+

2381 """, 

+

2382 

+

2383 'test.out': """\ 

+

2384 //**( 

+

2385 cog.outl("void %s();" % "MyFunction") 

+

2386 //]]] 

+

2387 void MyFunction(); 

+

2388 //[[[end]]] 

+

2389 """, 

+

2390 } 

+

2391 

+

2392 makeFiles(d) 

+

2393 self.cog.callableMain([ 

+

2394 'argv0', '-r', 

+

2395 '--markers=**( ]]] [[[end]]]', 

+

2396 'test.cog' 

+

2397 ]) 

+

2398 self.assertFilesSame('test.cog', 'test.out') 

2399 

-

2400 def testDeleteCodeWithDashRFails(self): 

-

2401 d = { 

-

2402 'test.cog': """\ 

-

2403 // This is my C++ file. 

-

2404 """ 

-

2405 } 

-

2406 

-

2407 makeFiles(d) 

-

2408 with self.assertRaisesRegex(CogUsageError, r"^Can't use -d with -r \(or you would delete all your source!\)$"): 

-

2409 self.cog.callableMain(['argv0', '-r', '-d', 'test.cog']) 

-

2410 

-

2411 def testSettingGlobals(self): 

-

2412 # Blake Winton contributed a way to set the globals that will be used in 

-

2413 # processFile(). 

-

2414 d = { 

-

2415 'test.cog': """\ 

-

2416 // This is my C++ file. 

-

2417 //[[[cog 

-

2418 for fn in fnames: 

-

2419 cog.outl("void %s();" % fn) 

-

2420 //]]] 

-

2421 Some Sample Code Here 

-

2422 //[[[end]]]""", 

-

2423 

-

2424 'test.out': """\ 

-

2425 // This is my C++ file. 

-

2426 void DoBlake(); 

-

2427 void DoWinton(); 

-

2428 void DoContribution(); 

-

2429 """, 

-

2430 } 

+

2400 

+

2401class BlakeTests(TestCaseWithTempDir): 

+

2402 

+

2403 # Blake Winton's contributions. 

+

2404 def testDeleteCode(self): 

+

2405 # -o sets the output file. 

+

2406 d = { 

+

2407 'test.cog': """\ 

+

2408 // This is my C++ file. 

+

2409 //[[[cog 

+

2410 fnames = ['DoSomething', 'DoAnotherThing', 'DoLastThing'] 

+

2411 for fn in fnames: 

+

2412 cog.outl("void %s();" % fn) 

+

2413 //]]] 

+

2414 Some Sample Code Here 

+

2415 //[[[end]]]Data Data 

+

2416 And Some More 

+

2417 """, 

+

2418 

+

2419 'test.out': """\ 

+

2420 // This is my C++ file. 

+

2421 void DoSomething(); 

+

2422 void DoAnotherThing(); 

+

2423 void DoLastThing(); 

+

2424 And Some More 

+

2425 """, 

+

2426 } 

+

2427 

+

2428 makeFiles(d) 

+

2429 self.cog.callableMain(['argv0', '-d', '-o', 'test.cogged', 'test.cog']) 

+

2430 self.assertFilesSame('test.cogged', 'test.out') 

2431 

-

2432 makeFiles(d) 

-

2433 globals = {} 

-

2434 globals['fnames'] = ['DoBlake', 'DoWinton', 'DoContribution'] 

-

2435 self.cog.options.bDeleteCode = True 

-

2436 self.cog.processFile('test.cog', 'test.cogged', globals=globals) 

-

2437 self.assertFilesSame('test.cogged', 'test.out') 

+

2432 def testDeleteCodeWithDashRFails(self): 

+

2433 d = { 

+

2434 'test.cog': """\ 

+

2435 // This is my C++ file. 

+

2436 """ 

+

2437 } 

2438 

-

2439 

-

2440class ErrorCallTests(TestCaseWithTempDir): 

-

2441 

-

2442 def testErrorCallHasNoTraceback(self): 

-

2443 # Test that cog.error() doesn't show a traceback. 

-

2444 d = { 

-

2445 'error.cog': """\ 

-

2446 //[[[cog 

-

2447 cog.error("Something Bad!") 

-

2448 //]]] 

-

2449 //[[[end]]] 

-

2450 """, 

-

2451 } 

-

2452 

-

2453 makeFiles(d) 

-

2454 self.cog.main(['argv0', '-r', 'error.cog']) 

-

2455 output = self.output.getvalue() 

-

2456 self.assertEqual(output, "Cogging error.cog\nError: Something Bad!\n") 

-

2457 

-

2458 def testRealErrorHasTraceback(self): 

-

2459 # Test that a genuine error does show a traceback. 

-

2460 d = { 

-

2461 'error.cog': """\ 

-

2462 //[[[cog 

-

2463 raise RuntimeError("Hey!") 

-

2464 //]]] 

-

2465 //[[[end]]] 

-

2466 """, 

-

2467 } 

-

2468 

-

2469 makeFiles(d) 

-

2470 self.cog.main(['argv0', '-r', 'error.cog']) 

-

2471 output = self.output.getvalue() 

-

2472 msg = 'Actual output:\n' + output 

-

2473 self.assertTrue(output.startswith("Cogging error.cog\nTraceback (most recent"), msg) 

-

2474 self.assertIn("RuntimeError: Hey!", output) 

-

2475 

-

2476 

-

2477# Things not yet tested: 

-

2478# - A bad -w command (currently fails silently). 

+

2439 makeFiles(d) 

+

2440 with self.assertRaisesRegex(CogUsageError, r"^Can't use -d with -r \(or you would delete all your source!\)$"): 

+

2441 self.cog.callableMain(['argv0', '-r', '-d', 'test.cog']) 

+

2442 

+

2443 def testSettingGlobals(self): 

+

2444 # Blake Winton contributed a way to set the globals that will be used in 

+

2445 # processFile(). 

+

2446 d = { 

+

2447 'test.cog': """\ 

+

2448 // This is my C++ file. 

+

2449 //[[[cog 

+

2450 for fn in fnames: 

+

2451 cog.outl("void %s();" % fn) 

+

2452 //]]] 

+

2453 Some Sample Code Here 

+

2454 //[[[end]]]""", 

+

2455 

+

2456 'test.out': """\ 

+

2457 // This is my C++ file. 

+

2458 void DoBlake(); 

+

2459 void DoWinton(); 

+

2460 void DoContribution(); 

+

2461 """, 

+

2462 } 

+

2463 

+

2464 makeFiles(d) 

+

2465 globals = {} 

+

2466 globals['fnames'] = ['DoBlake', 'DoWinton', 'DoContribution'] 

+

2467 self.cog.options.bDeleteCode = True 

+

2468 self.cog.processFile('test.cog', 'test.cogged', globals=globals) 

+

2469 self.assertFilesSame('test.cogged', 'test.out') 

+

2470 

+

2471 

+

2472class ErrorCallTests(TestCaseWithTempDir): 

+

2473 

+

2474 def testErrorCallHasNoTraceback(self): 

+

2475 # Test that cog.error() doesn't show a traceback. 

+

2476 d = { 

+

2477 'error.cog': """\ 

+

2478 //[[[cog 

+

2479 cog.error("Something Bad!") 

+

2480 //]]] 

+

2481 //[[[end]]] 

+

2482 """, 

+

2483 } 

+

2484 

+

2485 makeFiles(d) 

+

2486 self.cog.main(['argv0', '-r', 'error.cog']) 

+

2487 output = self.output.getvalue() 

+

2488 self.assertEqual(output, "Cogging error.cog\nError: Something Bad!\n") 

+

2489 

+

2490 def testRealErrorHasTraceback(self): 

+

2491 # Test that a genuine error does show a traceback. 

+

2492 d = { 

+

2493 'error.cog': """\ 

+

2494 //[[[cog 

+

2495 raise RuntimeError("Hey!") 

+

2496 //]]] 

+

2497 //[[[end]]] 

+

2498 """, 

+

2499 } 

+

2500 

+

2501 makeFiles(d) 

+

2502 self.cog.main(['argv0', '-r', 'error.cog']) 

+

2503 output = self.output.getvalue() 

+

2504 msg = 'Actual output:\n' + output 

+

2505 self.assertTrue(output.startswith("Cogging error.cog\nTraceback (most recent"), msg) 

+

2506 self.assertIn("RuntimeError: Hey!", output) 

+

2507 

+

2508 

+

2509# Things not yet tested: 

+

2510# - A bad -w command (currently fails silently). 

diff --git a/doc/sample_html/d_7b071bdc2a35fa80_test_makefiles_py.html b/doc/sample_html/d_7b071bdc2a35fa80_test_makefiles_py.html index 0dda0a3e5..2e440600d 100644 --- a/doc/sample_html/d_7b071bdc2a35fa80_test_makefiles_py.html +++ b/doc/sample_html/d_7b071bdc2a35fa80_test_makefiles_py.html @@ -185,8 +185,8 @@

diff --git a/doc/sample_html/d_7b071bdc2a35fa80_test_whiteutils_py.html b/doc/sample_html/d_7b071bdc2a35fa80_test_whiteutils_py.html index d345280df..382d43287 100644 --- a/doc/sample_html/d_7b071bdc2a35fa80_test_whiteutils_py.html +++ b/doc/sample_html/d_7b071bdc2a35fa80_test_whiteutils_py.html @@ -164,8 +164,8 @@

diff --git a/doc/sample_html/d_7b071bdc2a35fa80_whiteutils_py.html b/doc/sample_html/d_7b071bdc2a35fa80_whiteutils_py.html index 0f1b743d0..187d03fa7 100644 --- a/doc/sample_html/d_7b071bdc2a35fa80_whiteutils_py.html +++ b/doc/sample_html/d_7b071bdc2a35fa80_whiteutils_py.html @@ -136,8 +136,8 @@

diff --git a/doc/sample_html/index.html b/doc/sample_html/index.html index df751432d..38db89060 100644 --- a/doc/sample_html/index.html +++ b/doc/sample_html/index.html @@ -11,7 +11,7 @@

Coverage report: - 39.98% + 40.00%

@@ -81,12 +81,12 @@

Coverage report: cogapp/cogapp.py - 486 - 215 + 495 + 219 1 - 200 - 28 - 49.42% + 208 + 30 + 49.50% cogapp/makefiles.py @@ -99,12 +99,12 @@

Coverage report: cogapp/test_cogapp.py - 788 - 547 + 795 + 553 8 20 0 - 30.07% + 29.94% cogapp/test_makefiles.py @@ -137,12 +137,12 @@

Coverage report: Total - 1513 - 899 + 1529 + 909 9 - 278 - 34 - 39.98% + 286 + 36 + 40.00% @@ -153,8 +153,8 @@

Coverage report: diff --git a/doc/sample_html/status.json b/doc/sample_html/status.json index 668e809cb..1e4e99a58 100644 --- a/doc/sample_html/status.json +++ b/doc/sample_html/status.json @@ -1 +1 @@ -{"format":2,"version":"6.1.1","globals":"39f446cd732e316017c8c9fa061ccf97","files":{"d_7b071bdc2a35fa80___init___py":{"hash":"1fc4f9498f460d6c93280e8962ee0c0f","index":{"nums":[2,1,2,0,0,0,0,0],"html_filename":"d_7b071bdc2a35fa80___init___py.html","relative_filename":"cogapp/__init__.py"}},"d_7b071bdc2a35fa80___main___py":{"hash":"ffe6befa655d4d0b0b31eb0c73811311","index":{"nums":[2,1,3,0,3,0,0,0],"html_filename":"d_7b071bdc2a35fa80___main___py.html","relative_filename":"cogapp/__main__.py"}},"d_7b071bdc2a35fa80_backward_py":{"hash":"32afb71b2a11dd4b8ca4ed66b6815d42","index":{"nums":[2,1,22,0,6,4,2,2],"html_filename":"d_7b071bdc2a35fa80_backward_py.html","relative_filename":"cogapp/backward.py"}},"d_7b071bdc2a35fa80_cogapp_py":{"hash":"f3523a775c5c1d12a213eead8df82291","index":{"nums":[2,1,486,1,215,200,28,132],"html_filename":"d_7b071bdc2a35fa80_cogapp_py.html","relative_filename":"cogapp/cogapp.py"}},"d_7b071bdc2a35fa80_makefiles_py":{"hash":"85ec1064ff86d94238a8d7b76a2178a5","index":{"nums":[2,1,27,0,20,14,0,14],"html_filename":"d_7b071bdc2a35fa80_makefiles_py.html","relative_filename":"cogapp/makefiles.py"}},"d_7b071bdc2a35fa80_test_cogapp_py":{"hash":"6985a05ab5a9b347b3665136686f6fb1","index":{"nums":[2,1,788,8,547,20,0,18],"html_filename":"d_7b071bdc2a35fa80_test_cogapp_py.html","relative_filename":"cogapp/test_cogapp.py"}},"d_7b071bdc2a35fa80_test_makefiles_py":{"hash":"647f7dc911c97a6e646a91c3300a25ff","index":{"nums":[2,1,71,0,53,6,0,6],"html_filename":"d_7b071bdc2a35fa80_test_makefiles_py.html","relative_filename":"cogapp/test_makefiles.py"}},"d_7b071bdc2a35fa80_test_whiteutils_py":{"hash":"9476b26e42e6169b1857cfe7f29bf954","index":{"nums":[2,1,69,0,50,0,0,0],"html_filename":"d_7b071bdc2a35fa80_test_whiteutils_py.html","relative_filename":"cogapp/test_whiteutils.py"}},"d_7b071bdc2a35fa80_whiteutils_py":{"hash":"cf00c3e6149e4b80a2d01b6919c066a4","index":{"nums":[2,1,45,0,5,34,4,4],"html_filename":"d_7b071bdc2a35fa80_whiteutils_py.html","relative_filename":"cogapp/whiteutils.py"}}}} \ No newline at end of file +{"format":2,"version":"6.1.2","globals":"39f446cd732e316017c8c9fa061ccf97","files":{"d_7b071bdc2a35fa80___init___py":{"hash":"1fc4f9498f460d6c93280e8962ee0c0f","index":{"nums":[2,1,2,0,0,0,0,0],"html_filename":"d_7b071bdc2a35fa80___init___py.html","relative_filename":"cogapp/__init__.py"}},"d_7b071bdc2a35fa80___main___py":{"hash":"ffe6befa655d4d0b0b31eb0c73811311","index":{"nums":[2,1,3,0,3,0,0,0],"html_filename":"d_7b071bdc2a35fa80___main___py.html","relative_filename":"cogapp/__main__.py"}},"d_7b071bdc2a35fa80_backward_py":{"hash":"32afb71b2a11dd4b8ca4ed66b6815d42","index":{"nums":[2,1,22,0,6,4,2,2],"html_filename":"d_7b071bdc2a35fa80_backward_py.html","relative_filename":"cogapp/backward.py"}},"d_7b071bdc2a35fa80_cogapp_py":{"hash":"436496c809378ac1ec6dffa35b3ce048","index":{"nums":[2,1,495,1,219,208,30,136],"html_filename":"d_7b071bdc2a35fa80_cogapp_py.html","relative_filename":"cogapp/cogapp.py"}},"d_7b071bdc2a35fa80_makefiles_py":{"hash":"85ec1064ff86d94238a8d7b76a2178a5","index":{"nums":[2,1,27,0,20,14,0,14],"html_filename":"d_7b071bdc2a35fa80_makefiles_py.html","relative_filename":"cogapp/makefiles.py"}},"d_7b071bdc2a35fa80_test_cogapp_py":{"hash":"0734976cc61e29b326701651bb685257","index":{"nums":[2,1,795,8,553,20,0,18],"html_filename":"d_7b071bdc2a35fa80_test_cogapp_py.html","relative_filename":"cogapp/test_cogapp.py"}},"d_7b071bdc2a35fa80_test_makefiles_py":{"hash":"647f7dc911c97a6e646a91c3300a25ff","index":{"nums":[2,1,71,0,53,6,0,6],"html_filename":"d_7b071bdc2a35fa80_test_makefiles_py.html","relative_filename":"cogapp/test_makefiles.py"}},"d_7b071bdc2a35fa80_test_whiteutils_py":{"hash":"9476b26e42e6169b1857cfe7f29bf954","index":{"nums":[2,1,69,0,50,0,0,0],"html_filename":"d_7b071bdc2a35fa80_test_whiteutils_py.html","relative_filename":"cogapp/test_whiteutils.py"}},"d_7b071bdc2a35fa80_whiteutils_py":{"hash":"cf00c3e6149e4b80a2d01b6919c066a4","index":{"nums":[2,1,45,0,5,34,4,4],"html_filename":"d_7b071bdc2a35fa80_whiteutils_py.html","relative_filename":"cogapp/whiteutils.py"}}}} \ No newline at end of file