test_case_generator 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/test_case_generator/cli.rb +2 -0
- data/lib/test_case_generator/dsl_context.rb +65 -0
- data/lib/test_case_generator/generator_cplusplus.rb +86 -0
- data/lib/test_case_generator/generator_java.rb +39 -13
- data/lib/test_case_generator/generator_php.rb +40 -4
- data/lib/test_case_generator/generator_python.rb +43 -5
- data/lib/test_case_generator/state_machine.rb +128 -0
- data/lib/test_case_generator/utils.rb +53 -0
- data/lib/test_case_generator/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eaf8f594bdd3875c4f28d422053be70b8bb833ff
|
4
|
+
data.tar.gz: 97b3477ddd6a9128074a316f8679cf1071ee2d4c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 878c20c974e98c99b8836af666db046618e4220bdf9e670b5c97fc436c7aab409712b32c6c793c069fb93be3acc58ad480faa5f04891b2e348b5dc73a2f258e6
|
7
|
+
data.tar.gz: 64475acb5c35699342caf6126f71e833b11b2c45ac7d15225bbc044ddab2e6f95ad9a1dfb97724b8afc8aa0d110d1b19778e51e255cffe28d58f66a05df07602
|
@@ -8,6 +8,7 @@ require 'test_case_generator/generator_java'
|
|
8
8
|
require 'test_case_generator/generator_php'
|
9
9
|
require 'test_case_generator/generator_python'
|
10
10
|
require 'test_case_generator/generator_javascript'
|
11
|
+
require 'test_case_generator/generator_cplusplus'
|
11
12
|
|
12
13
|
module TestCaseGenerator
|
13
14
|
class CLI < Thor
|
@@ -24,6 +25,7 @@ module TestCaseGenerator
|
|
24
25
|
factory.register TestCaseGenerator::GeneratorPHP.new
|
25
26
|
factory.register TestCaseGenerator::GeneratorPython.new
|
26
27
|
factory.register TestCaseGenerator::GeneratorJavaScript.new
|
28
|
+
factory.register TestCaseGenerator::GeneratorCplusplus.new
|
27
29
|
|
28
30
|
gen = factory.query source_fn
|
29
31
|
gen.write ctx, source_fn
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'test_case_generator/utils'
|
2
|
+
require 'test_case_generator/state_machine'
|
2
3
|
|
3
4
|
module TestCaseGenerator
|
4
5
|
class DSLContext
|
5
6
|
attr_reader :children
|
6
7
|
attr_reader :labels
|
8
|
+
attr_reader :class_name
|
7
9
|
|
8
10
|
def initialize
|
9
11
|
@patterns = []
|
@@ -11,6 +13,7 @@ module TestCaseGenerator
|
|
11
13
|
@after = []
|
12
14
|
@children = []
|
13
15
|
@labels = []
|
16
|
+
@class_name = nil
|
14
17
|
end
|
15
18
|
|
16
19
|
def <<(events)
|
@@ -127,6 +130,68 @@ module TestCaseGenerator
|
|
127
130
|
end
|
128
131
|
alias_method :para, :parallel
|
129
132
|
|
133
|
+
def def_state_machine(options={}, &block)
|
134
|
+
ctx = StateMachineContext.new(options)
|
135
|
+
ctx.instance_eval &block if block_given?
|
136
|
+
ctx
|
137
|
+
end
|
138
|
+
|
139
|
+
def state_machine(options={}, &block)
|
140
|
+
ctx = def_state_machine options, &block
|
141
|
+
|
142
|
+
ctx.items.each do |x|
|
143
|
+
@patterns << x
|
144
|
+
x.each do |label|
|
145
|
+
@labels << label unless @labels.include? label
|
146
|
+
end
|
147
|
+
end
|
148
|
+
# @patterns.concat ctx.items
|
149
|
+
end
|
150
|
+
|
151
|
+
def add_async_events(src_items, options={})
|
152
|
+
out_items = []
|
153
|
+
|
154
|
+
src_items.each do |pattern1|
|
155
|
+
idx_from = options[:from].nil? ? nil : pattern1.find_index{|item| item==options[:from]}
|
156
|
+
if idx_from.nil?
|
157
|
+
out_items << pattern1
|
158
|
+
next
|
159
|
+
end
|
160
|
+
|
161
|
+
pattern2 = pattern1[idx_from + 1 ... pattern1.size]
|
162
|
+
idx_to = options[:to].nil? ? nil : pattern2.find_index{|item| item==options[:to]}
|
163
|
+
|
164
|
+
tmp_items = idx_to.nil? ? [pattern2] : [pattern2[0 ... idx_to]]
|
165
|
+
Utils.para! tmp_items, options[:items]
|
166
|
+
|
167
|
+
out_items.concat tmp_items.map{ |ptn| pattern1[0 .. idx_from] + ptn + (idx_to.nil? ? [] : pattern2[idx_to ... pattern2.size]) }
|
168
|
+
end
|
169
|
+
|
170
|
+
out_items.uniq
|
171
|
+
end
|
172
|
+
|
173
|
+
def add_async_events!(src_items, options={})
|
174
|
+
tmp_items = add_async_events(src_items, options)
|
175
|
+
|
176
|
+
src_items.clear
|
177
|
+
src_items.concat tmp_items
|
178
|
+
src_items
|
179
|
+
end
|
180
|
+
|
181
|
+
def add_patterns(patterns)
|
182
|
+
@patterns.concat patterns
|
183
|
+
|
184
|
+
patterns.each do |pattern|
|
185
|
+
pattern.each do |label|
|
186
|
+
@labels << label unless @labels.include? label
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def set_class_name(class_name)
|
192
|
+
@class_name = class_name
|
193
|
+
end
|
194
|
+
|
130
195
|
def raw_each
|
131
196
|
@patterns.each { |ptn| yield @before + ptn + @after }
|
132
197
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'test_case_generator/dsl_context'
|
2
|
+
require 'test_case_generator/indented_writer'
|
3
|
+
|
4
|
+
module TestCaseGenerator
|
5
|
+
class GeneratorCplusplus
|
6
|
+
def can_handle?(source_fn)
|
7
|
+
File.extname(source_fn).eql? '.cpp'
|
8
|
+
end
|
9
|
+
|
10
|
+
def write(ctx, source_fn)
|
11
|
+
write_skeleton source_fn unless File.exist? source_fn
|
12
|
+
write_source ctx, source_fn
|
13
|
+
end
|
14
|
+
|
15
|
+
def make_class_name(filename)
|
16
|
+
File.basename filename, '.*'
|
17
|
+
end
|
18
|
+
|
19
|
+
def write_skeleton(source_fn)
|
20
|
+
class_name = make_class_name(source_fn)
|
21
|
+
File.open(source_fn, 'w') do |f|
|
22
|
+
writer = IndentedWriter.new f
|
23
|
+
writer.puts <<EOS
|
24
|
+
#include <gtest/gtest.h>
|
25
|
+
|
26
|
+
class #{class_name} : public testing::Test
|
27
|
+
{
|
28
|
+
protected:
|
29
|
+
// TODO: Declares the variables your tests want to use.
|
30
|
+
|
31
|
+
protected:
|
32
|
+
virtual void SetUp() {
|
33
|
+
}
|
34
|
+
|
35
|
+
virtual void TearDown() {
|
36
|
+
}
|
37
|
+
|
38
|
+
protected:
|
39
|
+
// TODO: ここにアクションを書いてください
|
40
|
+
};
|
41
|
+
|
42
|
+
// %%
|
43
|
+
EOS
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def write_source(dsl_context, source_fn)
|
48
|
+
class_name = make_class_name(source_fn)
|
49
|
+
tmp_fn = source_fn + '.tmp'
|
50
|
+
source = File.open(source_fn).read
|
51
|
+
File.open(tmp_fn, 'w') do |f|
|
52
|
+
source.each_line do |line|
|
53
|
+
f.puts line
|
54
|
+
break if line =~ /^\s*\/\/\s*%%\s*$/
|
55
|
+
end
|
56
|
+
|
57
|
+
writer = IndentedWriter.new f
|
58
|
+
writer.blank
|
59
|
+
writer.puts '//'
|
60
|
+
writer.puts '// 以下の行は自動生成されているので直接編集しないでください。'
|
61
|
+
writer.puts '//'
|
62
|
+
writer.puts '// Generated by Test Case Generator'
|
63
|
+
writer.puts '// https://rubygems.org/gems/test_case_generator'
|
64
|
+
writer.puts '//'
|
65
|
+
|
66
|
+
dsl_context.each do |pattern|
|
67
|
+
method_name = pattern.join '_'
|
68
|
+
writer.blank
|
69
|
+
writer.puts "TEST_F(#{class_name}, #{method_name}) {"
|
70
|
+
|
71
|
+
pattern.each do |ptn|
|
72
|
+
writer.block_indent ' ' do
|
73
|
+
writer.puts "#{ptn}();"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
writer.puts '}'
|
78
|
+
end
|
79
|
+
|
80
|
+
# writer.blank
|
81
|
+
end
|
82
|
+
|
83
|
+
FileUtils.move tmp_fn, source_fn
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -9,7 +9,7 @@ module TestCaseGenerator
|
|
9
9
|
|
10
10
|
def write(ctx, source_fn)
|
11
11
|
write_skeleton source_fn unless File.exist? source_fn
|
12
|
-
write_interface ctx, File.join(File.dirname(source_fn), make_interface_name(source_fn)) + '.java'
|
12
|
+
write_interface ctx, File.join(File.dirname(source_fn), make_interface_name(source_fn)) + '.java', make_package_name(source_fn)
|
13
13
|
write_source ctx, source_fn
|
14
14
|
end
|
15
15
|
|
@@ -51,21 +51,46 @@ import org.junit.Before;
|
|
51
51
|
import org.junit.Test;
|
52
52
|
import org.junit.runner.RunWith;
|
53
53
|
import org.robolectric.Robolectric;
|
54
|
+
import org.robolectric.RobolectricGradleTestRunner;
|
54
55
|
import org.robolectric.RobolectricTestRunner;
|
55
56
|
import org.robolectric.annotation.Config;
|
56
57
|
|
58
|
+
import java.util.ArrayList;
|
59
|
+
|
57
60
|
import static org.junit.Assert.*;
|
58
61
|
|
59
|
-
@RunWith(
|
60
|
-
@Config(
|
62
|
+
@RunWith(RobolectricGradleTestRunner.class)
|
63
|
+
@Config(constants = BuildConfig.class, sdk = 18)
|
61
64
|
public class #{class_name} implements #{make_interface_name source_fn} {
|
62
65
|
|
63
66
|
@Before
|
64
67
|
public void setUp() {
|
68
|
+
Robolectric.getForegroundThreadScheduler().reset();
|
69
|
+
Robolectric.getForegroundThreadScheduler().pause();
|
70
|
+
Robolectric.getBackgroundThreadScheduler().reset();
|
71
|
+
Robolectric.getBackgroundThreadScheduler().pause();
|
65
72
|
}
|
66
73
|
|
67
74
|
@After
|
68
75
|
public void tearDown() {
|
76
|
+
Robolectric.getForegroundThreadScheduler().reset();
|
77
|
+
Robolectric.getForegroundThreadScheduler().unPause();
|
78
|
+
Robolectric.getBackgroundThreadScheduler().reset();
|
79
|
+
Robolectric.getBackgroundThreadScheduler().unPause();
|
80
|
+
}
|
81
|
+
|
82
|
+
// TODO: Please implement custom actions here.
|
83
|
+
|
84
|
+
private void printPatterns(String patterns) {
|
85
|
+
System.err.println("<<TEST>> " + patterns);
|
86
|
+
}
|
87
|
+
|
88
|
+
private void runPendingTasks() {
|
89
|
+
Robolectric.getForegroundThreadScheduler().advanceBy(1);
|
90
|
+
}
|
91
|
+
|
92
|
+
private void runTimerTasks() {
|
93
|
+
Robolectric.getForegroundThreadScheduler().advanceBy(30 * 1000);
|
69
94
|
}
|
70
95
|
|
71
96
|
// %%
|
@@ -74,17 +99,16 @@ EOS
|
|
74
99
|
end
|
75
100
|
end
|
76
101
|
|
77
|
-
def write_interface(dsl_context, header_fn)
|
102
|
+
def write_interface(dsl_context, header_fn, package_name)
|
78
103
|
interface_name = File.basename(header_fn, File.extname(header_fn))
|
79
104
|
tmp_fn = header_fn + '.tmp'
|
80
105
|
File.open(tmp_fn, 'w') do |f|
|
81
106
|
writer = IndentedWriter.new f
|
107
|
+
writer.puts <<EOS
|
108
|
+
package #{package_name};
|
82
109
|
|
83
|
-
|
84
|
-
|
85
|
-
writer.blank
|
86
|
-
writer.puts "public interface #{interface_name} {"
|
87
|
-
|
110
|
+
public interface #{interface_name} {
|
111
|
+
EOS
|
88
112
|
writer.block_indent ' ' do
|
89
113
|
dsl_context.labels.each do |label|
|
90
114
|
method_name = label
|
@@ -92,7 +116,9 @@ EOS
|
|
92
116
|
end
|
93
117
|
end
|
94
118
|
|
95
|
-
writer.puts
|
119
|
+
writer.puts <<EOS
|
120
|
+
}
|
121
|
+
EOS
|
96
122
|
end
|
97
123
|
|
98
124
|
FileUtils.move tmp_fn, header_fn
|
@@ -124,9 +150,9 @@ EOS
|
|
124
150
|
writer.blank
|
125
151
|
writer.puts '@Test'
|
126
152
|
writer.puts "public void test_#{method_name}() {"
|
127
|
-
|
128
|
-
|
129
|
-
|
153
|
+
writer.block_indent ' ' do
|
154
|
+
writer.puts "printPatterns(\"#{pattern.map{|p| "#{p}"}.join(', ')}\");"
|
155
|
+
pattern.each do |ptn|
|
130
156
|
writer.puts "#{ptn}();"
|
131
157
|
end
|
132
158
|
end
|
@@ -8,18 +8,45 @@ module TestCaseGenerator
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def write(ctx, source_fn)
|
11
|
-
|
11
|
+
write_skeleton source_fn unless File.exist? source_fn
|
12
|
+
write_interface ctx, File.join(File.dirname(source_fn), File.basename(source_fn, File.extname(source_fn)) + 'Generated.php')
|
12
13
|
write_source ctx, source_fn
|
13
14
|
end
|
14
15
|
|
15
|
-
def
|
16
|
-
|
16
|
+
def make_class_name(filename)
|
17
|
+
# File.join(File.dirname(source_fn), File.basename(source_fn, File.extname(source_fn))
|
18
|
+
File.basename filename, '.*'
|
19
|
+
end
|
20
|
+
|
21
|
+
def make_interface_name(filename)
|
22
|
+
make_class_name(filename) + 'Generated'
|
23
|
+
end
|
24
|
+
|
25
|
+
def write_skeleton(source_fn)
|
26
|
+
class_name = make_class_name(source_fn)
|
27
|
+
File.open(source_fn, 'w') do |f|
|
28
|
+
writer = IndentedWriter.new f
|
29
|
+
writer.puts <<EOS
|
30
|
+
<?php
|
31
|
+
require_once '#{make_interface_name source_fn}.php';
|
32
|
+
|
33
|
+
class #{class_name} extends PHPUnit_Framework_TestCase implements #{make_interface_name source_fn}
|
34
|
+
{
|
35
|
+
// %%
|
36
|
+
}
|
37
|
+
EOS
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def write_interface(dsl_context, header_fn)
|
42
|
+
interface_name = File.basename(header_fn, File.extname(header_fn))
|
17
43
|
tmp_fn = header_fn + '.tmp'
|
18
44
|
File.open(tmp_fn, 'w') do |f|
|
19
45
|
writer = IndentedWriter.new f
|
20
46
|
|
47
|
+
writer.puts '<?php'
|
21
48
|
writer.blank
|
22
|
-
writer.puts "interface #{
|
49
|
+
writer.puts "interface #{interface_name} {"
|
23
50
|
|
24
51
|
writer.block_indent ' ' do
|
25
52
|
dsl_context.labels.each do |label|
|
@@ -44,6 +71,15 @@ module TestCaseGenerator
|
|
44
71
|
end
|
45
72
|
|
46
73
|
writer = IndentedWriter.new f
|
74
|
+
writer.blank
|
75
|
+
writer.block_indent ' ' do
|
76
|
+
writer.puts '//'
|
77
|
+
writer.puts '// 以下の行は自動生成されているので直接編集しないでください。'
|
78
|
+
writer.puts '//'
|
79
|
+
writer.puts '// Generated by Test Case Generator'
|
80
|
+
writer.puts '// https://rubygems.org/gems/test_case_generator'
|
81
|
+
writer.puts '//'
|
82
|
+
end
|
47
83
|
|
48
84
|
dsl_context.each do |pattern|
|
49
85
|
method_name = pattern.join '_'
|
@@ -8,7 +8,7 @@ module TestCaseGenerator
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def write(ctx, source_fn)
|
11
|
-
write_skeleton source_fn unless File.exist? source_fn
|
11
|
+
write_skeleton ctx, source_fn unless File.exist? source_fn
|
12
12
|
write_source ctx, source_fn
|
13
13
|
end
|
14
14
|
|
@@ -16,8 +16,8 @@ module TestCaseGenerator
|
|
16
16
|
File.basename filename, '.*'
|
17
17
|
end
|
18
18
|
|
19
|
-
def write_skeleton(source_fn)
|
20
|
-
class_name = make_class_name(source_fn)
|
19
|
+
def write_skeleton(dsl_context, source_fn)
|
20
|
+
class_name = dsl_context.class_name || make_class_name(source_fn)
|
21
21
|
File.open(source_fn, 'w') do |f|
|
22
22
|
writer = IndentedWriter.new f
|
23
23
|
writer.puts <<EOS
|
@@ -26,22 +26,59 @@ module TestCaseGenerator
|
|
26
26
|
import os
|
27
27
|
import sys
|
28
28
|
import unittest
|
29
|
+
# from assets.stub_android import stub_api_model
|
30
|
+
# from assets.stub_android import stub_android
|
31
|
+
|
32
|
+
|
33
|
+
def print_patterns(patterns):
|
34
|
+
def wrapper(fn):
|
35
|
+
def _(self):
|
36
|
+
print
|
37
|
+
print "<<TEST>> %s" % (", ".join(patterns))
|
38
|
+
fn(self)
|
39
|
+
return _
|
40
|
+
return wrapper
|
41
|
+
|
42
|
+
|
43
|
+
def run_pending_tasks(fn):
|
44
|
+
def _(self):
|
45
|
+
fn(self)
|
46
|
+
|
47
|
+
while len(self.pending_tasks) > 0:
|
48
|
+
# http://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list-in-python
|
49
|
+
# Use instead of a weird syntax new_list = old_list[:]
|
50
|
+
pending_tasks = list(self.pending_tasks)
|
51
|
+
self.pending_tasks[:] = []
|
52
|
+
|
53
|
+
for task in pending_tasks:
|
54
|
+
task() # Maybe added into self.pending_tasks
|
55
|
+
|
56
|
+
return _
|
29
57
|
|
30
58
|
|
31
59
|
class #{class_name}(unittest.TestCase):
|
32
60
|
def setUp(self):
|
33
61
|
super(#{class_name}, self).setUp()
|
62
|
+
self.pending_tasks = []
|
63
|
+
self.timer_tasks = []
|
34
64
|
|
35
65
|
def tearDown(self):
|
36
66
|
super(#{class_name}, self).tearDown()
|
37
67
|
|
38
|
-
|
68
|
+
def _run_timer_tasks(self):
|
69
|
+
timer_tasks = list(self.timer_tasks)
|
70
|
+
self.timer_tasks[:] = []
|
71
|
+
|
72
|
+
for task in timer_tasks:
|
73
|
+
task() # Maybe added into self.timer_tasks
|
74
|
+
|
75
|
+
# %%
|
39
76
|
EOS
|
40
77
|
end
|
41
78
|
end
|
42
79
|
|
43
80
|
def write_source(dsl_context, source_fn)
|
44
|
-
class_name = make_class_name(source_fn)
|
81
|
+
class_name = dsl_context.class_name || make_class_name(source_fn)
|
45
82
|
tmp_fn = source_fn + '.tmp'
|
46
83
|
source = File.open(source_fn).read
|
47
84
|
File.open(tmp_fn, 'w') do |f|
|
@@ -65,6 +102,7 @@ EOS
|
|
65
102
|
method_name = pattern.join '_'
|
66
103
|
writer.block_indent ' ' do
|
67
104
|
writer.blank
|
105
|
+
writer.puts "@print_patterns([#{pattern.map{|p| "'#{p}'"}.join(', ')}])"
|
68
106
|
writer.puts "def test_#{method_name}(self):"
|
69
107
|
|
70
108
|
pattern.each do |ptn|
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'test_case_generator/utils'
|
2
|
+
|
3
|
+
module TestCaseGenerator
|
4
|
+
class Path
|
5
|
+
attr_reader :src_state, :dest_state
|
6
|
+
|
7
|
+
def initialize(src_state, dest_state, attrs={})
|
8
|
+
@src_state = src_state
|
9
|
+
@dest_state = dest_state
|
10
|
+
@attrs = attrs
|
11
|
+
end
|
12
|
+
|
13
|
+
def items
|
14
|
+
@attrs[:items] || []
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class State
|
19
|
+
attr_reader :name
|
20
|
+
|
21
|
+
def initialize(name, attrs={})
|
22
|
+
@name = name
|
23
|
+
@attrs = attrs
|
24
|
+
end
|
25
|
+
|
26
|
+
def items
|
27
|
+
@attrs[:items] || []
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Fork
|
32
|
+
attr_reader :state
|
33
|
+
|
34
|
+
def initialize(state, attrs={})
|
35
|
+
@state = state
|
36
|
+
@attrs = attrs
|
37
|
+
end
|
38
|
+
|
39
|
+
def items
|
40
|
+
@attrs[:items] || []
|
41
|
+
end
|
42
|
+
|
43
|
+
# def join
|
44
|
+
# @attrs[:join]
|
45
|
+
# end
|
46
|
+
end
|
47
|
+
|
48
|
+
class StateMachineContext
|
49
|
+
def initialize(attrs={})
|
50
|
+
@attrs = attrs
|
51
|
+
|
52
|
+
@state_list = []
|
53
|
+
@path_list = []
|
54
|
+
@fork_list = []
|
55
|
+
@start_state = attrs[:start_state]
|
56
|
+
@reject_block = nil
|
57
|
+
@filter_block = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_state(name, options={})
|
61
|
+
ctx = State.new(name, options)
|
62
|
+
@state_list << ctx
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_path(src_state, dest_state, options={})
|
66
|
+
ctx = Path.new(src_state, dest_state, options)
|
67
|
+
@path_list << ctx
|
68
|
+
end
|
69
|
+
|
70
|
+
def reject(&block)
|
71
|
+
@reject_block = block
|
72
|
+
end
|
73
|
+
|
74
|
+
def filter(&block)
|
75
|
+
@filter_block = block
|
76
|
+
end
|
77
|
+
|
78
|
+
def fork(state, options={})
|
79
|
+
@fork_list << Fork.new(state, options)
|
80
|
+
end
|
81
|
+
|
82
|
+
def start_state
|
83
|
+
if @start_state.nil?
|
84
|
+
@state_list[0]
|
85
|
+
else
|
86
|
+
@state_list.find{ |state| state.name == @start_state }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def items(options={})
|
91
|
+
out_items = []
|
92
|
+
counter = {}
|
93
|
+
_items! out_items, counter, start_state, options
|
94
|
+
out_items.uniq!
|
95
|
+
out_items.reject! &(@reject_block) unless @reject_block.nil?
|
96
|
+
out_items.keep_if &(@filter_block) unless @filter_block.nil?
|
97
|
+
|
98
|
+
p out_items
|
99
|
+
out_items
|
100
|
+
end
|
101
|
+
|
102
|
+
def _items!(out_items, counter, state, options={})
|
103
|
+
return if state.nil?
|
104
|
+
|
105
|
+
count = counter[state.name] || 0
|
106
|
+
count += 1
|
107
|
+
counter[state.name] = count
|
108
|
+
|
109
|
+
return if count > (options[:limit] || 2)
|
110
|
+
|
111
|
+
Utils.concat! out_items, state.items
|
112
|
+
|
113
|
+
tmp_list0 = []
|
114
|
+
@path_list.find_all{|path| path.src_state == state.name}.each do |path|
|
115
|
+
tmp_list = []
|
116
|
+
Utils.concat! tmp_list, path.items
|
117
|
+
_items! tmp_list, counter.clone, @state_list.find{ |s| s.name == path.dest_state}
|
118
|
+
tmp_list0.concat tmp_list
|
119
|
+
end
|
120
|
+
|
121
|
+
@fork_list.find_all{|fork| fork.state == state.name}.each do |fork|
|
122
|
+
Utils.para! tmp_list0, fork.items
|
123
|
+
end
|
124
|
+
|
125
|
+
Utils.concat! out_items, tmp_list0
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -5,5 +5,58 @@ module TestCaseGenerator
|
|
5
5
|
buffer << (buffer.empty? ? e : e.capitalize)
|
6
6
|
end.join
|
7
7
|
end
|
8
|
+
|
9
|
+
def self.concat!(out_items, other_list)
|
10
|
+
if out_items.size == 0
|
11
|
+
out_items.concat other_list
|
12
|
+
else
|
13
|
+
return out_items if other_list.empty?
|
14
|
+
|
15
|
+
tmp_list = []
|
16
|
+
out_items.each do |item1|
|
17
|
+
other_list.each do |item2|
|
18
|
+
tmp_list << item1 + item2
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
out_items.clear
|
23
|
+
out_items.concat tmp_list
|
24
|
+
end
|
25
|
+
|
26
|
+
out_items
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.para!(out_items, other_list)
|
30
|
+
if out_items.size == 0
|
31
|
+
out_items.concat other_list
|
32
|
+
else
|
33
|
+
return out_items if other_list.empty?
|
34
|
+
tmp_list = []
|
35
|
+
out_items.each do |item1|
|
36
|
+
other_list.each do |item2|
|
37
|
+
(0...(item1.size + item2.size)).to_a.combination(item1.size) do |index_arr|
|
38
|
+
idx_item1 = 0
|
39
|
+
idx_item2 = 0
|
40
|
+
tmp_list << (0...(item1.size + item2.size)).to_a.map do |x|
|
41
|
+
if index_arr.include?(x)
|
42
|
+
picked = item1[idx_item1]
|
43
|
+
idx_item1 += 1
|
44
|
+
else
|
45
|
+
picked = item2[idx_item2]
|
46
|
+
idx_item2 += 1
|
47
|
+
end
|
48
|
+
|
49
|
+
picked
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
out_items.clear
|
56
|
+
out_items.concat tmp_list
|
57
|
+
end
|
58
|
+
|
59
|
+
out_items
|
60
|
+
end
|
8
61
|
end
|
9
62
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: test_case_generator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kaoru Yanase
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -104,6 +104,7 @@ files:
|
|
104
104
|
- lib/test_case_generator.rb
|
105
105
|
- lib/test_case_generator/cli.rb
|
106
106
|
- lib/test_case_generator/dsl_context.rb
|
107
|
+
- lib/test_case_generator/generator_cplusplus.rb
|
107
108
|
- lib/test_case_generator/generator_factory.rb
|
108
109
|
- lib/test_case_generator/generator_java.rb
|
109
110
|
- lib/test_case_generator/generator_javascript.rb
|
@@ -111,6 +112,7 @@ files:
|
|
111
112
|
- lib/test_case_generator/generator_php.rb
|
112
113
|
- lib/test_case_generator/generator_python.rb
|
113
114
|
- lib/test_case_generator/indented_writer.rb
|
115
|
+
- lib/test_case_generator/state_machine.rb
|
114
116
|
- lib/test_case_generator/utils.rb
|
115
117
|
- lib/test_case_generator/version.rb
|
116
118
|
- test_case_generator.gemspec
|