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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 656a3c2e29e60d4eab8d44b0c4d43c33ed8ae08c
4
- data.tar.gz: 4468e1db4ea928e417869e4ae9666cee4e83ec68
3
+ metadata.gz: eaf8f594bdd3875c4f28d422053be70b8bb833ff
4
+ data.tar.gz: 97b3477ddd6a9128074a316f8679cf1071ee2d4c
5
5
  SHA512:
6
- metadata.gz: d6df9fd3d3dde363eb7a3159585f7287fa08f810bd4374042bf154bf167082f94a73b334e27f780cc4ac0a249fd47bfd442e1082beea86db930b6cda2432f848
7
- data.tar.gz: 6f66ed720bdf352e70aa3253d1996a620eaf07972b3da778b6dc08705b19231788f504eff4fe0336c74de263441519dbcfc8e2238d7f7bbf75a457f1cd8c5ba9
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(RobolectricTestRunner.class)
60
- @Config(emulateSdk = 18)
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
- writer.blank
84
- writer.puts '//'
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
- pattern.each do |ptn|
129
- writer.block_indent ' ' do
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
- write_header ctx, File.join(File.dirname(source_fn), File.basename(source_fn, File.extname(source_fn)) + 'Generated.php')
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 write_header(dsl_context, header_fn)
16
- protocol_name = File.basename(header_fn, File.extname(header_fn))
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 #{protocol_name} {"
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
@@ -1,3 +1,3 @@
1
1
  module TestCaseGenerator
2
- VERSION = '0.2.2'
2
+ VERSION = '0.3.0'
3
3
  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.2.2
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: 2015-08-31 00:00:00.000000000 Z
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