Subversion Repositories wimsdev

Rev

Rev 8192 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8192 Rev 10454
Line 4... Line 4...
4
 
4
 
5
titlePattern=re.compile(r"^== (.*) ==$")
5
titlePattern = re.compile(r"^== (.*) ==$")
6
varPattern=re.compile(r"^(.*) == (.*)$")
6
varPattern = re.compile(r"^(.*) == (.*)$")
7
rulePattern=re.compile(r"^----.*$")
7
rulePattern = re.compile(r"^----.*$")
8
commentPattern=re.compile(r"^\s*#.*$")
8
commentPattern = re.compile(r"^\s*#.*$")
9
codingPattern=re.compile(r"^# -\*- coding: (.*) -\*-$")
9
codingPattern = re.compile(r"^# -\*- coding: (.*) -\*-$")
10
 
10
 
11
locale.setlocale(locale.LC_ALL, '')
11
locale.setlocale(locale.LC_ALL, '')
12
codeset=locale.nl_langinfo(locale.CODESET) # coding used by the user's locale
12
codeset = locale.nl_langinfo(locale.CODESET)  # coding used by the user's locale
-
 
13
 
13
 
14
 
14
def notAtest(f):
15
def notAtest(f):
15
    """
16
    """
16
    consider some filenames as not useable to perfom tests.
17
    consider some filenames as not useable to perfom tests.
17
    @param f a filename
18
    @param f a filename
18
    @return True if f seems to be the name of a backup file
19
    @return True if f seems to be the name of a backup file
19
    """
20
    """
20
    return re.match(r".*~",f) or re.match(r".*\.bak",f)
21
    return re.match(r".*~", f) or re.match(r".*\.bak", f)
-
 
22
 
21
 
23
 
22
def mkTestList(lines, cur, title, coding="utf-8"):
24
def mkTestList(lines, cur, title, coding="utf-8"):
23
    """
25
    """
24
    makes a list of objects for unitary tests of Wims modtool primitives
26
    makes a list of objects for unitary tests of Wims modtool primitives
25
    @param lines a list of lines coming from a file
27
    @param lines a list of lines coming from a file
26
    @param cur a pointer on the current line to be read
28
    @param cur a pointer on the current line to be read
27
    @param title a title which has been read from a previous line
29
    @param title a title which has been read from a previous line
28
    @param coding the coding of the .proc file used for tests
30
    @param coding the coding of the .proc file used for tests
29
    @return a list of Test objects
31
    @return a list of Test objects
30
    """
32
    """
31
    result=[]
33
    result = []
32
    proclines=[]
34
    proclines = []
33
    variables={}
35
    variables = {}
34
    currentVar=None
36
    currentVar = None
35
    while cur < len(lines):
37
    while cur < len(lines):
36
        l=lines[cur].decode(coding).replace('\n','')
38
        l = lines[cur].decode(coding).replace('\n', '')
37
        t=titlePattern.match(l)
39
        t = titlePattern.match(l)
38
        v=varPattern.match(l)
40
        v = varPattern.match(l)
39
        r=rulePattern.match(l)
41
        r = rulePattern.match(l)
40
        c=commentPattern.match(l)
42
        c = commentPattern.match(l)
41
        if t:
43
        if t:
42
            result.append(Test(title, proclines, variables, coding))
44
            result.append(Test(title, proclines, variables, coding))
43
            title=t.group(1)
45
            title = t.group(1)
44
            proclines=[]
46
            proclines = []
45
            variables={}
47
            variables = {}
46
            currentVar=None
48
            currentVar = None
47
        elif v:
49
        elif v:
48
            currentVar=v.group(1)
50
            currentVar = v.group(1)
49
            variables[currentVar]=v.group(2)
51
            variables[currentVar] = v.group(2)
50
        elif currentVar!=None and len(l)>0:
52
        elif currentVar is not None and len(l) > 0:
51
            variables[currentVar]+='\n'+l
53
            variables[currentVar] += '\n' + l
52
        elif not r and not c:
54
        elif not r and not c:
53
            # not a title, nor variable, nor a ruler, nor a comment:
55
            # not a title, nor variable, nor a ruler, nor a comment:
54
            # these are commands
56
            # these are commands
55
            proclines.append(lines[cur].strip())
57
            proclines.append(lines[cur].strip())
56
        cur = cur+1
58
        cur = cur + 1
57
    result.append(Test(title, proclines, variables, coding))
59
    result.append(Test(title, proclines, variables, coding))
58
    return result
60
    return result
-
 
61
 
59
 
62
 
60
class Test:
63
class Test:
61
    """
64
    """
62
    This class implements data for a unitary test of Wims.
65
    This class implements data for a unitary test of Wims.
63
    Each test has a title, a set of lines to be pasted into
66
    Each test has a title, a set of lines to be pasted into
Line 73... Line 76...
73
        .proc file.
76
        .proc file.
74
        @param variables a dictionary associating variable names with
77
        @param variables a dictionary associating variable names with
75
        values they should have when the test finishes.
78
        values they should have when the test finishes.
76
        @param coding the coding used for the .proc file
79
        @param coding the coding used for the .proc file
77
        """
80
        """
78
        self.title=""+title
81
        self.title = "" + title
79
        self.proclines=copy.copy(proclines)
82
        self.proclines = copy.copy(proclines)
80
        self.variables=copy.copy(variables)
83
        self.variables = copy.copy(variables)
81
        self.coding=coding
84
        self.coding = coding
82
        self.gotResults={}
85
        self.gotResults = {}
83
        self.errors=[]
86
        self.errors = []
84
        self.success=None
87
        self.success = None
85
 
88
 
86
    def __str__(self):
89
    def __str__(self):
87
        """
90
        """
88
        Conversion to a str.
91
        Conversion to a str.
89
        """
92
        """
90
        result="Test {title=«%s»," %(self.title,)
93
        result = "Test {title=«%s»," % (self.title,)
91
        result+=" coding=%s," %self.coding
94
        result += " coding=%s," % self.coding
92
        result+=" proclines=%s," %self.proclines
95
        result += " proclines=%s," % self.proclines
93
        result+=" variables=%s" %self.variables
96
        result += " variables=%s" % self.variables
94
        result+="}"
97
        result += "}"
95
        return result
98
        return result
96
 
99
 
97
    def __repr__(self):
100
    def __repr__(self):
98
        """
101
        """
99
        The representation is the same as the conversion to a str.
102
        The representation is the same as the conversion to a str.
100
        """
103
        """
101
        return self.__str__()
104
        return self.__str__()
102
   
105
 
103
    def gotError(self):
106
    def gotError(self):
104
        """
107
        """
105
        checks whether some error occurred
108
        checks whether some error occurred
106
        @return True if an error came out of the wims subprocess
109
        @return True if an error came out of the wims subprocess
107
        """
110
        """
108
        return len(self.errors)>1 or (len(self.errors)==1 and
111
        return len(self.errors) > 1 or (len(self.errors) == 1 and
109
                                       self.errors[0]!="")
112
                                        self.errors[0] != "")
110
 
113
 
111
    def run(self, path, fName="test.proc"):
114
    def run(self, path, fName="test.proc"):
112
        """
115
        """
113
        runs the unitary tests, and gather the results in
116
        runs the unitary tests, and gather the results in
114
        self.gotResults, self.errors and self.success
117
        self.gotResults, self.errors and self.success
115
        @param path a path to the .proc file
118
        @param path a path to the .proc file
116
        @param fName the name of the .proc file, defaults to "test.proc"
119
        @param fName the name of the .proc file, defaults to "test.proc"
117
        """
120
        """
118
        self.success=True
121
        self.success = True
119
        self.failedVars=[]
122
        self.failedVars = []
120
        cmd="./wims test %s %s '%s'" %(path,
123
        cmd = "./wims test %s %s '%s'" % (path,
121
                                     fName,
124
                                          fName,
122
                                     ' '.join([v for v in self.variables]))
125
                                          ' '.join([v for v in self.variables]))
123
        with open(os.path.join(path,fName), "wb") as outfile:
126
        with open(os.path.join(path, fName), "wb") as outfile:
124
            for l in self.proclines:
127
            for l in self.proclines:
125
                outfile.write(l+b'\n');
128
                outfile.write(l + b'\n')
126
            outfile.close()
129
            outfile.close()
127
            p=subprocess.Popen(cmd,
130
            p = subprocess.Popen(cmd,
128
                               shell=True,
131
                                 shell=True,
129
                               stdout=subprocess.PIPE,
132
                                 stdout=subprocess.PIPE,
130
                               stderr=subprocess.PIPE)
133
                                 stderr=subprocess.PIPE)
131
            out, err = p.communicate()
134
            out, err = p.communicate()
132
            currentVar=None
135
            currentVar = None
133
            for l in out.decode(self.coding).split("\n"):
136
            for l in out.decode(self.coding).split("\n"):
134
                v=varPattern.match(l)
137
                v = varPattern.match(l)
135
                if v:
138
                if v:
136
                    currentVar=v.group(1)
139
                    currentVar = v.group(1)
137
                    self.gotResults[currentVar]=v.group(2)
140
                    self.gotResults[currentVar] = v.group(2)
138
                else:
141
                else:
139
                    if currentVar!=None and len(l)>0:
142
                    if currentVar is not None and len(l) > 0:
140
                        # add an other line to the current variable
143
                        # add an other line to the current variable
141
                        self.gotResults[currentVar]+='\n'+l
144
                        self.gotResults[currentVar] += '\n' + l
142
            self.errors=err.decode(codeset).split("\n")
145
            self.errors = err.decode(codeset).split("\n")
143
            if self.gotError():
146
            if self.gotError():
144
                self.success=False
147
                self.success = False
145
            for v in self.variables:
148
            for v in self.variables:
146
                if v not in self.gotResults or self.variables[v]!=self.gotResults[v]:
149
                if v not in self.gotResults or self.variables[v] != self.gotResults[v]:
147
                    self.failedVars.append(v)
150
                    self.failedVars.append(v)
148
                    self.success=False
151
                    self.success = False
149
 
152
 
150
    def showResult(self, msg="", tmpDir="/tmp"):
153
    def showResult(self, msg="", tmpDir="/tmp"):
151
        """
154
        """
152
        runs the test if self.success is undefined, and
155
        runs the test if self.success is undefined, and
153
        pretty-prints the result
156
        pretty-prints the result
154
        @param msg a message string to prepend to the result (for instance,
157
        @param msg a message string to prepend to the result (for instance,
155
        a test number)
158
        a test number)
156
        @param tmpDir a directory to run the tests
159
        @param tmpDir a directory to run the tests
157
        """
160
        """
158
        if self.success==None:
161
        if self.success is None:
159
            self.run(tmpDir)
162
            self.run(tmpDir)
160
        if self.success:
163
        if self.success:
161
            print("[%s] %s: OK." %(msg, self.title))
164
            print("[%s] %s: OK." % (msg, self.title))
162
        else:
165
        else:
163
            hrule="[%s] ========< %s >=========="  %(msg, self.title)
166
            hrule = "[%s] ========< %s >==========" % (msg, self.title)
164
            print(hrule)
167
            print(hrule)
165
            for l in self.proclines:
168
            for l in self.proclines:
166
                print(l)
169
                print(l)
167
            hrule="="*len(hrule)
170
            hrule = "=" * len(hrule)
168
            print(hrule)
171
            print(hrule)
169
            if self.gotError():
172
            if self.gotError():
170
                print ("ERROR: %s" %self.errors)
173
                print ("ERROR: %s" % self.errors)
171
            for v in self.failedVars:
174
            for v in self.failedVars:
172
                if v in self.gotResults:
175
                if v in self.gotResults:
173
                    print("FAILED for variable %s, expected: «%s»; got: «%s»"
176
                    print("FAILED for variable %s, expected: «%s»; got: «%s»"
174
                          %(v, self.variables[v], self.gotResults[v]))
177
                          % (v, self.variables[v], self.gotResults[v]))
175
                else:
178
                else:
176
                    print("FAILED for variable %s, expected: «%s»; got nothing"
179
                    print("FAILED for variable %s, expected: «%s»; got nothing"
177
                          %(v, self.variables[v]))
180
                          % (v, self.variables[v]))
178
                for v in self.variables:
181
                for v in self.variables:
179
                    if v not in self.failedVars:
182
                    if v not in self.failedVars:
180
                        print("OK for variable %s,  expected: «%s»; got: «%s»"
183
                        print("OK for variable %s,  expected: «%s»; got: «%s»"
181
                          %(v, self.variables[v], self.gotResults[v]))
184
                              % (v, self.variables[v], self.gotResults[v]))
182
                print(hrule)
185
                print(hrule)
183
           
-
 
184
 
186
 
185
 
187
 
186
if __name__ == "__main__":
188
if __name__ == "__main__":
187
    print ("Test suite for Wims.")
189
    print ("Test suite for Wims.")
188
    for dirpath, dirnames, filenames in os.walk("test"):
190
    for dirpath, dirnames, filenames in os.walk("test"):
189
        for f in filenames:
191
        for f in filenames:
190
            if notAtest(f):
192
            if notAtest(f):
191
                continue
193
                continue
192
            lines=open(os.path.join(dirpath, f),"rb").readlines()
194
            lines = open(os.path.join(dirpath, f), "rb").readlines()
193
            cur=0
195
            cur = 0
194
            t=titlePattern.match(lines[cur].decode("utf-8"))
196
            t = titlePattern.match(lines[cur].decode("utf-8"))
195
            coding = "utf-8" # default
197
            coding = "utf-8"  # default
196
            while cur < len(lines) and not t:
198
            while cur < len(lines) and not t:
197
                # take in account coding declaration
199
                # take in account coding declaration
198
                c=codingPattern.match(lines[cur].decode("utf-8"))
200
                c = codingPattern.match(lines[cur].decode("utf-8"))
199
                if c:
201
                if c:
200
                    coding=c.group(1)
202
                    coding = c.group(1)
201
                cur+=1
203
                cur += 1
202
                t=titlePattern.match(lines[cur].decode(coding))
204
                t = titlePattern.match(lines[cur].decode(coding))
203
            if cur < len(lines):
205
            if cur < len(lines):
204
                print("Running tests from {}/{} (coding: {})".format(dirpath, f, coding))
206
                print("Running tests from {}/{} (coding: {})".format(dirpath, f, coding))
205
                title=t.group(1)
207
                title = t.group(1)
206
                tests=mkTestList(lines, cur, title, coding=coding)
208
                tests = mkTestList(lines, cur, title, coding=coding)
207
                with tempfile.TemporaryDirectory(prefix='wimstest-') as tmpDir:
209
                with tempfile.TemporaryDirectory(prefix='wimstest-') as tmpDir:
208
                    i=1
210
                    i = 1
209
                    ok=0
211
                    ok = 0
210
                    nok=0
212
                    nok = 0
211
                    for t in tests:
213
                    for t in tests:
212
                        t.showResult(tmpDir=tmpDir, msg=i)
214
                        t.showResult(tmpDir=tmpDir, msg=i)
213
                        i += 1
215
                        i += 1
214
                        if t.success:
216
                        if t.success:
215
                            ok+=1
217
                            ok += 1
216
                        else:
218
                        else:
217
                            nok+=1
219
                            nok += 1
218
                print ("Ran {} tests; {} OK, {} WRONG.".format(i-1,ok,nok))
220
                print ("Ran {} tests; {} OK, {} WRONG.".format(i - 1, ok, nok))
219
            else:
221
            else:
220
                print("Error: the first line of the file shouldcontain some == title ==")
222
                print("Error: the first line of the file should contain some == title ==")
221
                os.exit(1)
223
                os.exit(1)
222
 
-
 
223
 
-
 
224
               
-