test_generator 1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e7909cf0b3c6a8fdf7e19e25ffd386e52ffdbce97924609d33d7c9b26046d6f9
4
+ data.tar.gz: 2a103ab5ac36e823cda0bd6d312523440765c8d0983a92d194e16e08e9ab3a0c
5
+ SHA512:
6
+ metadata.gz: 5421450d717d4fe6044cb9d2dbf79ab389e1a16322123d4c40fec91fe49e19155053acacf566beaf4929fd6e187f1a1ffc570d059551218476ff56a6dceac4a8
7
+ data.tar.gz: bbf3b9d80c25c4c69a85d991cb092401b1f415bf841fa9e56058bcafcb52367a661754e9cdf2c9f9482d25535e4d083897839e9d5c47bff971ace4f34896fbd6
data/lib/ext/string.rb ADDED
@@ -0,0 +1,47 @@
1
+ class String
2
+ # strings de cada classe de equivalência para testes
3
+ INT_STRING = "3"
4
+ EMAIL_STRING = "genaina@email.com"
5
+ FLOAT_STRING = "3.14"
6
+ PHONE_STRING = "(61) 98999-9999"
7
+ DATE_STRING = "12/01/1997"
8
+
9
+ CUSTOM_METHODS = %w(is_i? is_email? is_float? is_phone? is_date?)
10
+
11
+ EQUIVALENCE_CLASSES = {
12
+ "is_i?" => "INTEGER",
13
+ "is_email?" => "EMAIL",
14
+ "is_float?" => "FLOAT",
15
+ "is_phone?" => "PHONE",
16
+ "is_date?" => "DATE",
17
+ }
18
+
19
+ STRINGS_EQUIVALENCE_CLASSES = {
20
+ "is_i?" => String::INT_STRING,
21
+ "is_email?" => String::EMAIL_STRING,
22
+ "is_float?" => String::FLOAT_STRING,
23
+ "is_phone?" => String::PHONE_STRING,
24
+ "is_date?" => String::DATE_STRING,
25
+ }
26
+
27
+ def is_i?
28
+ /\A[-+]?\d+\z/ === self
29
+ end
30
+
31
+ def is_email?
32
+ /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i === self
33
+ end
34
+
35
+ def is_float?
36
+ self.to_f.to_s === self
37
+ end
38
+
39
+ def is_phone?
40
+ /^\([1-9]{2}\) (?:[2-8]|9[1-9])[0-9]{3}\-[0-9]{4}$/ === self ||
41
+ /^\([1-9]{2}\)(?:[2-8]|9[1-9])[0-9]{3}\-[0-9]{4}$/ === self
42
+ end
43
+
44
+ def is_date?
45
+
46
+ end
47
+ end
@@ -0,0 +1,64 @@
1
+ require 'rails/generators/base'
2
+ class EquivalenceClassGenerator < Rails::Generators::Base
3
+ def create_equivalence_class_tests
4
+ require 'json'
5
+ require 'reflector'
6
+ class_name = args[0]
7
+ file_name = class_name.downcase
8
+ puts "criando testes unitarios para #{class_name}..."
9
+ is_controller = /.*Controller$/.match?(class_name)
10
+ class_type = "model"
11
+
12
+ template = %Q{require 'rails_helper'
13
+
14
+ RSpec.describe #{class_name}, :type => :#{class_type} do
15
+ }
16
+ equivalence_class_counter = {}
17
+ File.readlines("#{Rails.root}/tmp/#{class_name}.rb").each do |line|
18
+ json_string = JSON.parse(line.strip)
19
+ puts "\nReflecting..."
20
+ reflector = Reflect::Reflector.new
21
+ klass = json_string["klass"]
22
+ meth = json_string["method"]
23
+ cs = json_string["current_state"]
24
+ args = json_string["args"]
25
+ class_and_method_name = "#{klass}::#{meth}"
26
+
27
+ equivalence_class_counter[meth] ||= {}
28
+ args.each do |arg|
29
+ String::CUSTOM_METHODS.each do |equivalence_class_method|
30
+ respond_to_eq_class = arg.send(equivalence_class_method) # testa pra ver se responde à alguma classe de equivalencia
31
+ if respond_to_eq_class # se responder à classe, adiciona 1 ao contador daquela classe
32
+ if equivalence_class_counter[meth][equivalence_class_method].nil?
33
+ equivalence_class_counter[meth][equivalence_class_method] = 1
34
+ else
35
+ equivalence_class_counter[meth][equivalence_class_method] += 1
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ equivalence_class_counter.each do |method,stats| # pega o hash com os métodos e as estatísticas de cada
44
+ probabily_class = stats.max_by{|k,v| v}
45
+ template_aux = %Q{
46
+ describe '##{method}_equivalence_class' do
47
+ # #{probabily_class.last} entries with this class
48
+ it "arguments should belong to #{String::EQUIVALENCE_CLASSES[probabily_class.first]} equivalence class" do
49
+ expect(#{class_name.capitalize}).to receive(:#{method}).with("#{String::STRINGS_EQUIVALENCE_CLASSES[probabily_class.first]}")
50
+ User.find_by_email_address("#{String::STRINGS_EQUIVALENCE_CLASSES[probabily_class.first]}")
51
+ end
52
+ end
53
+ }
54
+ template.concat(template_aux)
55
+ end
56
+ puts equivalence_class_counter
57
+
58
+ template.concat(%Q{
59
+ end
60
+ })
61
+
62
+ create_file "spec/#{class_type}s/#{file_name}_equiv_spec.rb", template
63
+ end
64
+ end
@@ -0,0 +1,120 @@
1
+ require 'rails/generators/base'
2
+ class UnitTestGenerator < Rails::Generators::Base
3
+ def create_unit_tests
4
+ require 'json'
5
+ require 'reflector'
6
+ class_name = args[0]
7
+ file_name = class_name.downcase
8
+ puts "criando testes unitarios para #{class_name}..."
9
+ is_controller = /.*Controller$/.match?(class_name)
10
+ class_type = "model"
11
+ first_line = File.open("#{Rails.root}/tmp/#{class_name}.rb", &:readline)
12
+ sample_object = JSON.parse(first_line)["current_state"]
13
+
14
+ executed_methods = []
15
+ executed_arguments = {}
16
+ if is_controller
17
+ class_type = "controller"
18
+ template = %Q{require 'rails_helper'
19
+
20
+ RSpec.describe #{class_name}, :type => :#{class_type} do
21
+ }
22
+ File.readlines("#{Rails.root}/tmp/#{class_name}.rb").each do |line|
23
+ json_string = JSON.parse(line.strip)
24
+ puts "\nReflecting..."
25
+ reflector = Reflect::Reflector.new
26
+ klass = json_string["klass"]
27
+ meth = json_string["method"]
28
+ cs = json_string["current_state"]
29
+ args = json_string["args"]
30
+ class_and_method_name = "#{klass}::#{meth}"
31
+ if executed_methods.include?(class_and_method_name)
32
+ if executed_arguments[class_and_method_name.to_sym].include?(args)
33
+ # do nothing, same test
34
+ else
35
+ # same test with other arguments
36
+ executed_arguments[class_and_method_name.to_sym].push(args)
37
+ end
38
+ else # other test for other method
39
+ executed_methods.push(class_and_method_name)
40
+ executed_arguments[class_and_method_name.to_sym] = []
41
+ puts "Executando #{klass}::#{meth} com argumentos #{args} no objeto #{sample_object}"
42
+ reflection = reflector.reflect(klass, meth, sample_object, args)
43
+ puts "Resultado: #{reflection}"
44
+ print "\n"
45
+
46
+ template_aux = %Q{
47
+ describe 'GET #{meth}' do
48
+ it 'returns a successful response' do
49
+ get :#{meth}
50
+ expect(response).to be_successful
51
+ end
52
+
53
+ it 'renders the #{meth} template' do
54
+ get :#{meth}
55
+ expect(response).to render_template("#{meth}")
56
+ end
57
+ end
58
+ }
59
+ template.concat(template_aux)
60
+ end
61
+ end
62
+
63
+ template.concat(%Q{
64
+ end
65
+ })
66
+ else
67
+ template = %Q{require 'rails_helper'
68
+
69
+ RSpec.describe #{class_name}, :type => :#{class_type} do
70
+ let(:#{file_name}) { #{class_name}.new(#{sample_object}) }
71
+
72
+ it "is valid with valid attributes" do
73
+ expect(#{file_name}).to be_valid
74
+ end
75
+ }
76
+ File.readlines("#{Rails.root}/tmp/#{class_name}.rb").each do |line|
77
+ json_string = JSON.parse(line.strip)
78
+ puts "\nReflecting..."
79
+ reflector = Reflect::Reflector.new
80
+ klass = json_string["klass"]
81
+ meth = json_string["method"]
82
+ cs = json_string["current_state"]
83
+ args = json_string["args"]
84
+ class_and_method_name = "#{klass}::#{meth}"
85
+ if executed_methods.include?(class_and_method_name)
86
+ if executed_arguments[class_and_method_name.to_sym].include?(args)
87
+ # do nothing, same test
88
+ else
89
+ # same test with other arguments
90
+ executed_arguments[class_and_method_name.to_sym].push(args)
91
+ end
92
+ else # other test for other method
93
+ executed_methods.push(class_and_method_name)
94
+ executed_arguments[class_and_method_name.to_sym] = []
95
+ puts "Executando #{klass}::#{meth} com argumentos #{args} no objeto #{sample_object}"
96
+ reflection = reflector.reflect(klass, meth, sample_object, args)
97
+ puts "Resultado: #{reflection}"
98
+ print "\n"
99
+
100
+ template_aux = %Q{
101
+ describe '##{meth}' do
102
+ it "should return valid string for method #{meth}" do
103
+ expect(#{class_name.downcase}.#{meth}(#{args.join(', ')})).to eq "#{reflection}"
104
+ end
105
+ end
106
+ }
107
+ template.concat(template_aux)
108
+ end
109
+ end
110
+
111
+ template.concat(%Q{
112
+ end
113
+ })
114
+ end
115
+
116
+ create_file "spec/#{class_type}s/#{file_name.sub('controller', '_controller')}_spec.rb", template
117
+
118
+ puts "Testes criados."
119
+ end
120
+ end
data/lib/reflector.rb ADDED
@@ -0,0 +1,16 @@
1
+ module Reflect
2
+ class Reflector
3
+ def reflect(klass, method, attributes, args)
4
+ if attributes.nil?
5
+ @instance = Object.const_get(klass).new
6
+ else
7
+ @instance = Object.const_get(klass).new(attributes)
8
+ end
9
+ if Object.const_get(klass).respond_to?(method) # class method
10
+ Object.const_get(klass).send(method, *args)
11
+ else
12
+ @instance.send(method, *args)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,58 @@
1
+ require 'aquarium'
2
+ include Aquarium::Aspects
3
+
4
+ # Load Rails constants
5
+ Rails.application.eager_load!
6
+
7
+ # Get Rails models and controllers classes
8
+ controllers = ApplicationController.subclasses
9
+ models = ApplicationRecord.subclasses
10
+
11
+ puts "Aspects initialized"
12
+
13
+ Aspect.new(:around,
14
+ calls_to: :all_methods,
15
+ for_types: models + controllers,
16
+ method_options: [:exclude_ancestor_methods, :class]) do |jp, obj, *args|
17
+ begin
18
+ # Get class
19
+ klass = jp.target_type.name.constantize
20
+ # puts klass
21
+
22
+ # List all klass public instance methods
23
+ if models.include? klass
24
+ public_instance_methods = (klass.public_instance_methods - Object.public_instance_methods).sort
25
+ # puts public_instance_methods
26
+ end
27
+
28
+ # Get method
29
+ method = jp.method_name.to_sym
30
+ # puts method
31
+
32
+ # Get object current state
33
+ if models.include? klass
34
+ if obj.class == Class
35
+ else
36
+ current_state = obj.attributes
37
+ end
38
+ # puts current_state
39
+ end
40
+
41
+ # Create temp file
42
+ file_name ="#{Rails.root}/tmp/#{klass.to_s}.rb"
43
+
44
+ file = File.new(file_name, 'a')
45
+
46
+ str = "{ \"klass\": \"#{klass}\", \"method\": \"#{method}\", \"args\": #{args.inspect}, \"current_state\": #{current_state.to_json} }"
47
+
48
+ unless File.open(file_name).each_line.any? { |line| line.include?(str)}
49
+ file.puts str
50
+ end
51
+
52
+ jp.proceed
53
+ ensure
54
+ if file
55
+ file.close
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,13 @@
1
+ require 'rails/generators/base'
2
+
3
+ module TestGenerator
4
+ class InstallGenerator < Rails::Generators::Base
5
+ desc "Creates a aspects initializer file."
6
+ def create_aspect_initialize_file
7
+ template = File.read('./templates/aspects.rb')
8
+ create_file "config/initializers/aspects.rb", template
9
+
10
+ puts "Aspects Initializer created."
11
+ end
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: test_generator
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.1'
5
+ platform: ruby
6
+ authors:
7
+ - Nicholas Marques
8
+ - Rafael Fernandes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2020-07-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: 3.2.0
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: 3.2.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: cucumber-rails
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec-rails
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: aquarium
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ description: This gem will track everything users do in the system and map it into
71
+ controllers and model methods beeing called, and generate tests for them
72
+ email:
73
+ - nnmarques97@gmail.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - lib/ext/string.rb
79
+ - lib/generators/equivalence_class_generator.rb
80
+ - lib/generators/unit_test_generator.rb
81
+ - lib/reflector.rb
82
+ - lib/templates/aspects.rb
83
+ - lib/test_generator.rb
84
+ homepage: https://github.com/NickNish09/TestGenerator
85
+ licenses: []
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubygems_version: 3.0.6
103
+ signing_key:
104
+ specification_version: 4
105
+ summary: Auto generate tests based on system usage and BDD.
106
+ test_files: []