tset 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f27830bfa45780af901203d61a7fc1b52dc906dd
4
+ data.tar.gz: 73e19fa5e554d5ee50f6737bc05dbad47e077d43
5
+ SHA512:
6
+ metadata.gz: cf6b9261c29093169b72eb15291375d5fbce2e9190c9d163b10a6c71bee4137301d9609f8b6bab82a75036e9270508875c29375bc29befda0cb09677e56e0f70
7
+ data.tar.gz: 650a7258cad0b33de4f6df0075e2142dcea56e056d648d6d0d224881127e91bd8c3482b3236c4e387e1ad7c2a1a39b90449af5ca7cd28bf30fd7b114ab21315e
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'byebug', require: false
4
+
5
+ # Specify your gem's dependencies in tset.gemspec
6
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Sung Won Cho
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # Tset
2
+
3
+ Tset generates tests for your models in your Rails application.
4
+
5
+ ## Why?
6
+
7
+ TDD is great, but sometimes you just want to write some codes.
8
+
9
+ Enter 'Development Driven Test'. Tset enables you to just write codes and worry about tests later.
10
+
11
+ ## Installation
12
+
13
+ Run installation command.
14
+
15
+ ```
16
+ gem install tset
17
+ ```
18
+
19
+ OR if you are using bundler,
20
+
21
+ ```ruby
22
+ gem 'tset', group: :development
23
+ ```
24
+
25
+ Run `bundle`
26
+
27
+ ## Usage
28
+
29
+ In your application root directory, run the generator.
30
+
31
+ ```
32
+ tset generate model YOUR_MODEL_NAME
33
+ ```
34
+
35
+ Tset will read your model and generate a test accordingly.
36
+
37
+ By default, the Tset will use RSpec. Help us add MiniTest support by contributing.
38
+
39
+ ## Fact
40
+
41
+ * Tset is a test spelled backwards.
42
+
43
+ ## Contributing
44
+
45
+ ### TODO
46
+
47
+ * Help us improve Tset by adding more test rules located in translators.
48
+ * Support MiniTest.
49
+ * Support controllers.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "rspec/core/rake_task"
2
+ require "bundler/gem_tasks"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/tset ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "tset/cli"
4
+ Tset::Cli.start
@@ -0,0 +1,15 @@
1
+ module Tset
2
+ module Analyzers
3
+ #
4
+ # Abstract superclass for analyzers
5
+ #
6
+ # @abstract
7
+ #
8
+ class Abstract
9
+
10
+ def start
11
+ raise NotImplementedError
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ #
2
+ # Representation of action and its content in a controller
3
+ #
4
+ # @param name [String] a name of an action
5
+ # @param body [String] a content of an action
6
+ #
7
+ module Tset
8
+ module Analyzers
9
+ class Action
10
+
11
+ def initialize(name, body)
12
+ @name = name
13
+ @body = body
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,56 @@
1
+ require "tset/analyzers/abstract"
2
+ require "tset/translators/rspec"
3
+ require "tset/testable"
4
+ require "pathname"
5
+
6
+ # Reads the model file and breaks it down into an array of testables.
7
+ #
8
+ # @param name [String] the name of the model
9
+ # @return [Array] the model codes for which tests can be generated.
10
+ #
11
+ module Tset
12
+ module Analyzers
13
+ class Model < Abstract
14
+
15
+ attr_reader :name, :target
16
+
17
+ def initialize(name)
18
+ @name = name
19
+ @target = Pathname.pwd.join('app/models')
20
+ end
21
+
22
+ def start
23
+ detect_testable_lines
24
+ end
25
+
26
+ private
27
+
28
+ def detect_testable_lines
29
+ testable_lines = []
30
+
31
+ content = _model_file.read
32
+
33
+ testable_patterns.each do |pattern|
34
+ testable_lines << content.each_line.grep(pattern) do |matching_line|
35
+ Tset::Testable.new('model', matching_line.strip)
36
+ end
37
+ end
38
+
39
+ testable_lines.flatten
40
+ end
41
+
42
+ def _model_file
43
+ target.join("#{ name }.rb")
44
+ end
45
+
46
+ def testable_patterns
47
+ Tset::Translators::Rspec::MODEL_TRANSLATION_RULES.flat_map do |category|
48
+ category.values.flat_map do |rule|
49
+ rule.keys
50
+ end
51
+ end
52
+ end
53
+
54
+ end
55
+ end
56
+ end
data/lib/tset/cli.rb ADDED
@@ -0,0 +1,23 @@
1
+ require "thor"
2
+ require "tset/commands/generate"
3
+
4
+ module Tset
5
+ class Cli < Thor
6
+ include Thor::Actions
7
+
8
+ desc 'version', 'prints Tset version'
9
+ def version
10
+ puts "v#{ Tset::VERSION }"
11
+ end
12
+
13
+ desc 'generate', 'generates tests'
14
+ def generate(type = nil, name = nil, framework = 'rspec')
15
+ if options[:help] || (type.nil? && name.nil?)
16
+ invoke :help, ['generate']
17
+ else
18
+ require "tset/commands/generate"
19
+ Tset::Commands::Generate.new(type, name, framework, self).start
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,37 @@
1
+ require "pathname"
2
+ require "active_support/inflector"
3
+
4
+ module Tset
5
+ module Commands
6
+ class Generate
7
+
8
+ GENERATOR_NAMESPACE = "Tset::Generators::%sTest".freeze
9
+
10
+ class Error < ::StandardError ; end
11
+
12
+ attr_reader :type, :name, :framework, :cli, :source, :target
13
+
14
+ def initialize(type, name, framework, cli)
15
+ @type = type
16
+ @name = name.downcase
17
+ @framework = framework
18
+
19
+ @cli = cli
20
+ @source = Pathname.new(::File.dirname(__FILE__) + "/../generators/#{ @type }_test").realpath
21
+ @target = Pathname.pwd.realpath
22
+ end
23
+
24
+ def start
25
+ generator.start
26
+ end
27
+
28
+ private
29
+
30
+ def generator
31
+ require "tset/generators/#{ @type }_test"
32
+ class_name = @type.classify
33
+ Object.const_get(GENERATOR_NAMESPACE % class_name).new(self)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ require "delegate"
2
+
3
+ module Tset
4
+ module Generators
5
+ #
6
+ # An abstract superclass of Generators
7
+ #
8
+ # @param command [Tset::Commands::Generate] An instance of generate command
9
+ # @abstract
10
+ #
11
+ class Abstract < SimpleDelegator
12
+ def initialize(command)
13
+ super(command)
14
+ end
15
+
16
+ def start
17
+ raise NotImplementedError
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ require "tset/generators/abstract"
2
+
3
+ module Tset
4
+ module Generators
5
+ class ControllerTest < Abstract
6
+
7
+ def initialize(command)
8
+ super
9
+
10
+ cli.class.source_root(source)
11
+ end
12
+
13
+ def start
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe <%= config[:model_name] %> do
4
+ end
@@ -0,0 +1 @@
1
+ require 'test_helper'
@@ -0,0 +1,52 @@
1
+ require "tset/generators/abstract"
2
+ require "tset/analyzers/model"
3
+ require "tset/writers/model_test"
4
+ require "active_support/inflector"
5
+
6
+ module Tset
7
+ module Generators
8
+ #
9
+ # Generates blank test files in the application
10
+ # Uses analyzers, translators, and writers to insert appropriate tests into the files.
11
+ #
12
+ # @param command [Tset::Commands::Generate] An instance of generate command
13
+ #
14
+ class ModelTest < Abstract
15
+
16
+ attr_reader :model_name
17
+
18
+ def initialize(command)
19
+ super
20
+ @model_name = name.classify
21
+
22
+ cli.class.source_root(source)
23
+ end
24
+
25
+ def start
26
+ assert_model_exists!
27
+
28
+ opts = {
29
+ model_name: @model_name
30
+ }
31
+
32
+ case framework
33
+ when 'rspec'
34
+ cli.template(source.join('model_spec.rspec.tt'), target.join("spec/models/#{ name }_spec.rb"), opts)
35
+ when 'minitest'
36
+ cli.template(source.join('model_test.minitest.tt'), target.join("test/models/#{ name }_test.rb"), opts)
37
+ end
38
+
39
+ testables = Tset::Analyzers::Model.new(name).start
40
+ Tset::Writers::ModelTest.new(name, testables, framework).start!
41
+ end
42
+
43
+ private
44
+
45
+ def assert_model_exists!
46
+ unless target.join("app/models/#{ name }.rb").exist?
47
+ raise Tset::Commands::Generate::Error.new("Unknown model: `#{ name }`")
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
data/lib/tset/test.rb ADDED
@@ -0,0 +1,17 @@
1
+ module Tset
2
+ #
3
+ # Contains the translated test code and the category it belongs to
4
+ #
5
+ # @param code [String] The actual test code translated from testable
6
+ # @param category [String] A category used for describe block
7
+ #
8
+ class Test
9
+
10
+ attr_reader :code, :category
11
+
12
+ def initialize(code, category)
13
+ @code = code
14
+ @category = category
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ require "tset/translators/rspec"
2
+ require "tset/translators/minitest"
3
+ require "active_support/inflector"
4
+
5
+ module Tset
6
+ #
7
+ # Snippet of code that can be converted to a test by Writers
8
+ #
9
+ # @param type [String] The part of application from which the code originate (e.g. controller, model)
10
+ # @param code [String] The testable code itself
11
+ #
12
+ class Testable
13
+
14
+ TRANSLATOR_NAMESPACE = "Tset::Translators::%s"
15
+
16
+ attr_reader :type, :code
17
+
18
+ def initialize(type, code)
19
+ @type = type
20
+ @code = code
21
+ end
22
+
23
+ def to_test(framework = 'rspec')
24
+ translator(framework).start
25
+ end
26
+
27
+ private
28
+
29
+ def translator(framework)
30
+ class_name = framework.classify
31
+ Object.const_get(TRANSLATOR_NAMESPACE % class_name).new(self)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ module Tset
2
+ module Translators
3
+ #
4
+ # An abstract superclass for Translators
5
+ #
6
+ # @abstract
7
+ class Abstract
8
+
9
+ def start
10
+ raise NotImplementedError
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module Tset
2
+ module Translators
3
+ #
4
+ # Translates testable to a minitest test
5
+ #
6
+ # @param testable [Test::Testable] An instance of testable
7
+ #
8
+ class MiniTest < Abstract
9
+
10
+ def initialize(testable)
11
+ @testable = testable
12
+ end
13
+
14
+ def start
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,67 @@
1
+ require "tset/translators/abstract"
2
+
3
+ module Tset
4
+ module Translators
5
+ #
6
+ # Translates testable to an RSpec test
7
+ #
8
+ # @param testable [Test::Testable] An instance of testable
9
+ #
10
+ class Rspec < Abstract
11
+
12
+ MODEL_TRANSLATION_RULES = [
13
+ {
14
+ 'validations' => {
15
+ %r(validates_presence_of (.*)) => "it { is.expected_to validate_presence_of(%s) }",
16
+ %r(validates_uniqueness_of (.*)) => "it { is.expected_to validate_uniqueness_of(%s) }",
17
+ %r(validates_length_of (.*), maximum: (\d*)) => "it { is.expected_to ensure_length_of(%s).is_at_most(%s) }",
18
+ %r(validates_length_of (.*), minimum: (\d*)) => "it { is.expected_to ensure_length_of(%s).is_at_least(%s) }",
19
+ %r(validates (\S*), presence: true) => "it { is.expected_to validate_presence_of(%s) }"
20
+ }
21
+ },
22
+
23
+ {
24
+ 'associations' => {
25
+ %r(belongs_to (.*)) => "it { is.expected_to belong_to(%s) }",
26
+ %r(has_many (.*)) => "it { is.expected_to have_many(%s) }",
27
+ %r(has_one (.*)) => "it { is.expected_to have_one(%s) }",
28
+ %r(has_and_belongs_to_many (.*)) => "it { is.expected_to have_and_belong_to_many(%s) }",
29
+ %r(has_attached_file (\S*)) => "it { is.expected_to have_attached_file(%s) }"
30
+ }
31
+ }
32
+ ]
33
+
34
+ attr_reader :testable
35
+
36
+ def initialize(testable)
37
+ @testable = testable
38
+ end
39
+
40
+ #
41
+ # @return [Tset::Test] An object containing RSpec test corresponding to the testable and category
42
+ #
43
+ def start
44
+ send("translate_#{ testable.type }")
45
+ end
46
+
47
+ private
48
+
49
+ #
50
+ # Translates the testable from the object using MODEL_TRANSLATION_RULES
51
+ #
52
+ # @return [Tset::Test] an object containing corresponding test_code and category
53
+ #
54
+ def translate_model
55
+ MODEL_TRANSLATION_RULES.each do |rule|
56
+ rule.values.first.each do |pattern, outcome|
57
+ if testable.code =~ pattern
58
+ test_code = outcome % [$1, $2]
59
+ return Tset::Test.new(test_code, rule.keys.first)
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,3 @@
1
+ module Tset
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,15 @@
1
+ #
2
+ # Abstract superclass for Writers
3
+ #
4
+ # @abstract
5
+ #
6
+ module Tset
7
+ module Writers
8
+ class Abstract
9
+
10
+ def start!
11
+ raise NotImplementedError
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,89 @@
1
+ require "tset/writers/abstract"
2
+ require "active_support/inflector"
3
+
4
+ module Tset
5
+ module Writers
6
+ #
7
+ # Writes the test for a model for each testable codes given
8
+ #
9
+ # @param model_name [String] a name of the model (e.g. post)
10
+ # @param testables [Array] an array of lines of code returned by Tset::Analyzers::Model
11
+ # @param framework [String] a test framework. Default to 'rspec'.
12
+ #
13
+ class ModelTest < Abstract
14
+
15
+ attr_reader :model_name, :testables, :framework, :target
16
+
17
+ def initialize(model_name, testables, framework = 'rspec')
18
+ @model_name = model_name
19
+ @testables = testables
20
+ @framework = framework
21
+
22
+ @target = Pathname.pwd.realpath
23
+ end
24
+
25
+ #
26
+ # @return [String] A classified version of the name (e.g. Post)
27
+ #
28
+ def class_name
29
+ @class_name ||= model_name.classify
30
+ end
31
+
32
+ def start!
33
+ case framework
34
+ when 'rspec'
35
+ testables.each { |testable| write_rspec(testable) }
36
+ when 'minitest'
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ #
43
+ # Translates the testable into rspec and writes to rspec file
44
+ #
45
+ # @param testable [Tset::Testable]
46
+ #
47
+ def write_rspec(testable)
48
+ test = testable.to_test('rspec')
49
+
50
+ file_contents = File.read(_rspec_file)
51
+
52
+ describe(test.category) unless file_contents =~ /describe "#{test.category}" do/
53
+ expectation(test)
54
+ end
55
+
56
+ #
57
+ # Writes a describe block
58
+ #
59
+ # @param category [String] notion that is being described
60
+ #
61
+ def describe(category)
62
+ file_contents = File.read(_rspec_file)
63
+ replacement = %Q(describe #{class_name} do
64
+
65
+ describe "#{category}" do
66
+ end)
67
+ file_contents.gsub!(/describe #{class_name} do/, replacement)
68
+ File.write(_rspec_file, file_contents)
69
+ end
70
+
71
+ #
72
+ # Writes an expectation
73
+ #
74
+ # @param test [Tset::Tset]
75
+ #
76
+ def expectation(test)
77
+ file_contents = File.read(_rspec_file)
78
+ replacement = %Q( describe "#{test.category}" do
79
+ #{test.code})
80
+ file_contents.gsub!(/\s\sdescribe "#{test.category}" do/, replacement)
81
+ File.write(_rspec_file, file_contents)
82
+ end
83
+
84
+ def _rspec_file
85
+ target.join("spec/models/#{ @model_name }_spec.rb")
86
+ end
87
+ end
88
+ end
89
+ end
data/lib/tset.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "tset/version"
2
+
3
+ module Tset
4
+ require "tset/testable"
5
+ require "tset/cli"
6
+ end
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+
3
+ describe Tset::Analyzers::Model do
4
+ let(:name) { 'post' }
5
+ let(:analyzer) { Tset::Analyzers::Model.new(name) }
6
+
7
+ before do
8
+ set_up_testing_directory
9
+ create_file("app/models/#{name}.rb")
10
+ end
11
+
12
+ before(:each) do
13
+ erase_file_content("app/models/#{name}.rb")
14
+ end
15
+
16
+ after do
17
+ chdir_back_to_root
18
+ end
19
+
20
+ it 'returns an array of testable codes' do
21
+ content = "
22
+ belongs_to :author
23
+ has_one :tipjar
24
+ has_many :comments
25
+ has_many :likes
26
+ lets_validate_this :forum
27
+ validates_presence_of :post
28
+ acts_as_votable
29
+ validates_presence_of :author
30
+ validates :category, presence: true
31
+ "
32
+ insert_into_file("app/models/#{name}.rb", content)
33
+ result = analyzer.start
34
+
35
+ expect(result.map(&:code)).to match_array ['validates_presence_of :post', 'validates_presence_of :author', 'validates :category, presence: true',
36
+ 'belongs_to :author', 'has_one :tipjar', 'has_many :comments', 'has_many :likes']
37
+
38
+ end
39
+ end
@@ -0,0 +1,61 @@
1
+ require "spec_helper"
2
+
3
+ describe Tset::Commands::Generate do
4
+ let(:name) { 'post' }
5
+ let(:cli) { Tset::Cli.new }
6
+ let(:command) { Tset::Commands::Generate.new(type, name, framework, cli) }
7
+
8
+ before do
9
+ set_up_testing_directory
10
+ end
11
+
12
+ after do
13
+ chdir_back_to_root
14
+ end
15
+
16
+ describe 'model' do
17
+ let(:type) { 'model' }
18
+ let(:framework) { 'rspec' }
19
+
20
+ context 'when the model exists' do
21
+ before do
22
+ create_file("app/models/#{name}.rb")
23
+ end
24
+
25
+ context 'with rspec' do
26
+
27
+ before do
28
+ command.start
29
+ end
30
+
31
+ it 'generates a model spec' do
32
+ content = @root.join('spec/models/post_spec.rb').read
33
+ expect(content).to match %(require 'spec_helper')
34
+ expect(content).to match %(describe Post do)
35
+ end
36
+ end
37
+
38
+ context 'with minitest' do
39
+ let(:framework) { 'minitest' }
40
+
41
+ before do
42
+ command.start
43
+ end
44
+
45
+ it 'generates a model test' do
46
+ content = @root.join('test/models/post_test.rb').read
47
+ expect(content).to match %(require 'test_helper')
48
+ end
49
+ end
50
+ end
51
+
52
+ context 'when the model does not exist' do
53
+ it 'raises error' do
54
+ expect {
55
+ command.start
56
+ }.to raise_error(Tset::Commands::Generate::Error)
57
+ end
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,54 @@
1
+ require "spec_helper"
2
+
3
+ describe 'tset generate model post' do
4
+ let(:name) { 'post' }
5
+ let(:cli) { Tset::Cli.new }
6
+ let(:command) { Tset::Commands::Generate.new(type, name, framework, cli) }
7
+ let(:type) { 'model' }
8
+ let(:model_content) {
9
+ "validates_presence_of :author
10
+ validates_presence_of :title
11
+ validates_presence_of :body
12
+ validates_length_of :title, maximum: 30
13
+ validates_length_of :body, minimum: 50
14
+ belongs_to :author
15
+ has_and_belongs_to_many :categories
16
+ has_many :comments" }
17
+
18
+ before do
19
+ set_up_testing_directory
20
+ create_file("app/models/#{name}.rb")
21
+ insert_into_file("app/models/#{name}.rb", model_content)
22
+ end
23
+
24
+ after do
25
+ chdir_back_to_root
26
+ end
27
+
28
+ context 'with rspec' do
29
+ let(:framework) { 'rspec' }
30
+
31
+ before(:each) do
32
+ command.start
33
+ end
34
+
35
+ it 'generates the correct spec' do
36
+ content = @root.join('spec/models/post_spec.rb').read
37
+ expect(content).to match %(require 'spec_helper')
38
+ expect(content).to match %(describe Post do)
39
+ expect(content).to match %( describe "associations" do)
40
+ expect(content).to match %r( it { is.expected_to have_and_belong_to_many\(:categories\) })
41
+ expect(content).to match %r( it { is.expected_to have_many\(:comments\) })
42
+ expect(content).to match %r( it { is.expected_to belong_to\(:author\) })
43
+ expect(content).to match %( end)
44
+ expect(content).to match %( describe "validations" do)
45
+ expect(content).to match %r( it { is.expected_to validate_presence_of\(:author\))
46
+ expect(content).to match %r( it { is.expected_to validate_presence_of\(:title\) })
47
+ expect(content).to match %r( it { is.expected_to validate_presence_of\(:body\) })
48
+ expect(content).to match %r( it { is.expected_to ensure_length_of\(:title\).is_at_most\(30\) })
49
+ expect(content).to match %r( it { is.expected_to ensure_length_of\(:body\).is_at_least\(50\) })
50
+ expect(content).to match %( end)
51
+ expect(content).to match %(end)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,21 @@
1
+ # Require all files under /lib
2
+ Dir[File.expand_path('../../lib/**/*.rb', __FILE__)].each { |f| require f }
3
+
4
+ # Require all spec support files
5
+ Dir[File.expand_path('../support/**/*.rb', __FILE__)].each { |f| require f }
6
+
7
+ RSpec.configure do |config|
8
+ config.expect_with :rspec do |expectations|
9
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
10
+ end
11
+
12
+ config.mock_with :rspec do |mocks|
13
+ mocks.verify_partial_doubles = true
14
+ end
15
+
16
+ # Include support modules from support files
17
+ config.include SetupMacros
18
+
19
+ # Do not display console outputs when running tests
20
+ config.before { allow($stdout).to receive(:write) }
21
+ end
@@ -0,0 +1,34 @@
1
+ module SetupMacros
2
+ def set_up_testing_directory
3
+ @tmp = Pathname.new(@pwd = Dir.pwd).join('tmp')
4
+ @tmp.rmtree if @tmp.exist?
5
+ @tmp.mkpath
6
+
7
+ @tmp.join('apps/controllers').mkpath
8
+ @tmp.join('apps/models').mkpath
9
+
10
+ Dir.chdir(@tmp)
11
+ @root = @tmp
12
+ end
13
+
14
+ def chdir_back_to_root
15
+ Dir.chdir(@pwd)
16
+ end
17
+
18
+ def create_file(path)
19
+ file = @root.join(path)
20
+ file.dirname.rmtree if file.dirname.exist?
21
+ file.dirname.mkpath
22
+ FileUtils.touch(file)
23
+ end
24
+
25
+ def erase_file_content(path)
26
+ file = @root.join(path)
27
+ File.open(file, 'w') {}
28
+ end
29
+
30
+ def insert_into_file(path, content)
31
+ file = @root.join(path)
32
+ File.write(file, content)
33
+ end
34
+ end
@@ -0,0 +1,89 @@
1
+ require "spec_helper"
2
+
3
+ describe Tset::Translators::Rspec do
4
+ let(:translator) { Tset::Translators::Rspec.new(testable) }
5
+ let(:testable) { Tset::Testable.new('model', code) }
6
+ let(:result) { translator.start }
7
+
8
+ context 'for models' do
9
+ context 'validates_presence_of :post' do
10
+ let(:code) { 'validates_presence_of :post' }
11
+
12
+ it 'returns a proper test' do
13
+ expect(result.code).to eq "it { is.expected_to validate_presence_of(:post) }"
14
+ end
15
+ end
16
+
17
+ context 'validates_uniqueness_of :title' do
18
+ let(:code) { 'validates_uniqueness_of :title' }
19
+
20
+ it 'returns a proper test' do
21
+ expect(result.code).to eq "it { is.expected_to validate_uniqueness_of(:title) }"
22
+ end
23
+ end
24
+
25
+ context 'validates_uniqueness_of :title' do
26
+ let(:code) { 'validates_uniqueness_of :title' }
27
+
28
+ it 'returns a proper test' do
29
+ expect(result.code).to eq "it { is.expected_to validate_uniqueness_of(:title) }"
30
+ end
31
+ end
32
+
33
+ context 'validates_length_of :body, maximum: 300' do
34
+ let(:code) { 'validates_length_of :body, maximum: 300' }
35
+
36
+ it 'returns a proper test' do
37
+ expect(result.code).to eq "it { is.expected_to ensure_length_of(:body).is_at_most(300) }"
38
+ end
39
+ end
40
+
41
+ context 'validates_length_of :body, minimum: 100' do
42
+ let(:code) { 'validates_length_of :body, minimum: 100' }
43
+
44
+ it 'returns a proper test' do
45
+ expect(result.code).to eq "it { is.expected_to ensure_length_of(:body).is_at_least(100) }"
46
+ end
47
+ end
48
+
49
+ context 'belongs_to :author' do
50
+ let(:code) { 'belongs_to :author' }
51
+
52
+ it 'returns a proper test' do
53
+ expect(result.code).to eq "it { is.expected_to belong_to(:author) }"
54
+ end
55
+ end
56
+
57
+ context 'has_many :comments' do
58
+ let(:code) { 'has_many :comments' }
59
+
60
+ it 'returns a proper test' do
61
+ expect(result.code).to eq "it { is.expected_to have_many(:comments) }"
62
+ end
63
+ end
64
+
65
+ context 'has_one :tag' do
66
+ let(:code) { 'has_one :tag' }
67
+
68
+ it 'returns a proper test' do
69
+ expect(result.code).to eq "it { is.expected_to have_one(:tag) }"
70
+ end
71
+ end
72
+
73
+ context 'has_and_belongs_to_many :admins' do
74
+ let(:code) { 'has_and_belongs_to_many :admins' }
75
+
76
+ it 'returns a proper test' do
77
+ expect(result.code).to eq "it { is.expected_to have_and_belong_to_many(:admins) }"
78
+ end
79
+ end
80
+
81
+ context 'has_attached_file :profile_picture' do
82
+ let(:code) { 'has_attached_file :profile_picture' }
83
+
84
+ it 'returns a proper test' do
85
+ expect(result.code).to eq "it { is.expected_to have_attached_file(:profile_picture) }"
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe Tset::Writers::ModelTest do
4
+ let(:writer) { Tset::Writers::ModelTest.new(model_name, testables, framework) }
5
+ let(:model_name) { 'post' }
6
+
7
+ before do
8
+ set_up_testing_directory
9
+ create_file('app/models/post.rb')
10
+ create_file('spec/models/post_spec.rb')
11
+ insert_into_file('spec/models/post_spec.rb', "describe Post do")
12
+ end
13
+
14
+ after do
15
+ chdir_back_to_root
16
+ end
17
+
18
+ context 'rsepc' do
19
+ let(:framework) { 'rspec' }
20
+ let(:testables) { [Tset::Testable.new('model', 'validates_presence_of :author')] }
21
+
22
+ it 'writes a test' do
23
+ writer.start!
24
+
25
+ content = @root.join('spec/models/post_spec.rb').read
26
+ expect(content).to match %r(it { is.expected_to validate_presence_of\(:author\) })
27
+ end
28
+ end
29
+ end
data/tset.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tset/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tset"
8
+ spec.version = Tset::VERSION
9
+ spec.authors = ["Sung Won Cho"]
10
+ spec.email = ["mikeswcho@gmail.com"]
11
+ spec.summary = %q{Generate tests for your Rails model.}
12
+ spec.description = %q{Generate tests for your Rails model. Enter Development Driven Test.}
13
+ spec.homepage = "https://github.com/sungwoncho/tset"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.2.0"
24
+
25
+ spec.add_dependency "thor", "~> 0.19.1"
26
+ spec.add_dependency "activesupport", "~> 4.2.1"
27
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tset
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sung Won Cho
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.2.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.2.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: thor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.19.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.19.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 4.2.1
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 4.2.1
83
+ description: Generate tests for your Rails model. Enter Development Driven Test.
84
+ email:
85
+ - mikeswcho@gmail.com
86
+ executables:
87
+ - tset
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - bin/tset
98
+ - lib/tset.rb
99
+ - lib/tset/analyzers/abstract.rb
100
+ - lib/tset/analyzers/action.rb
101
+ - lib/tset/analyzers/model.rb
102
+ - lib/tset/cli.rb
103
+ - lib/tset/commands/generate.rb
104
+ - lib/tset/generators/abstract.rb
105
+ - lib/tset/generators/controller_test.rb
106
+ - lib/tset/generators/controller_test/ctrl_spec.rspec.tt
107
+ - lib/tset/generators/controller_test/ctrl_test.minitest.tt
108
+ - lib/tset/generators/model_test.rb
109
+ - lib/tset/generators/model_test/model_spec.rspec.tt
110
+ - lib/tset/generators/model_test/model_test.minitest.tt
111
+ - lib/tset/test.rb
112
+ - lib/tset/testable.rb
113
+ - lib/tset/translators/abstract.rb
114
+ - lib/tset/translators/minitest.rb
115
+ - lib/tset/translators/rspec.rb
116
+ - lib/tset/version.rb
117
+ - lib/tset/writers/abstract.rb
118
+ - lib/tset/writers/model_test.rb
119
+ - spec/analyzers/model_spec.rb
120
+ - spec/commands/generate_spec.rb
121
+ - spec/integration/generate_model_test_spec.rb
122
+ - spec/spec_helper.rb
123
+ - spec/support/setup_macros.rb
124
+ - spec/translators/rspec_spec.rb
125
+ - spec/writers/model_test_spec.rb
126
+ - tset.gemspec
127
+ homepage: https://github.com/sungwoncho/tset
128
+ licenses:
129
+ - MIT
130
+ metadata: {}
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 2.4.5
148
+ signing_key:
149
+ specification_version: 4
150
+ summary: Generate tests for your Rails model.
151
+ test_files:
152
+ - spec/analyzers/model_spec.rb
153
+ - spec/commands/generate_spec.rb
154
+ - spec/integration/generate_model_test_spec.rb
155
+ - spec/spec_helper.rb
156
+ - spec/support/setup_macros.rb
157
+ - spec/translators/rspec_spec.rb
158
+ - spec/writers/model_test_spec.rb