rails_zen 0.1.0

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
+ SHA1:
3
+ metadata.gz: ffdf4939e8dda4d2ca2dca549392f46b0a417a3a
4
+ data.tar.gz: 33d799f39f4be8726d9ba7b4f7da2a8b6a35acc7
5
+ SHA512:
6
+ metadata.gz: 4d845aade057e447bb8860e6179286e9628ec4b8e3194ff59690ca08774a6d504640d109297a5d5a67f012e4719750ef1b9576a2674477cfeaf4b1e2994c7d88
7
+ data.tar.gz: 2d67d68126efc3db3158436f616e16917e1ed2b57f47fe17473eedfe946c0e62adcc7383555d6f0f4741a3e4f62c7f946498945e84ac5564e62ece24e0afb9f5
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /bin/rspec
3
+ /bin/cucumber
4
+ /.yardoc
5
+ /Gemfile.lock
6
+ /_yardoc/
7
+ /coverage/
8
+ /doc/
9
+ /pkg/
10
+ /spec/reports/
11
+ /tmp/
12
+ *.bundle
13
+ *.so
14
+ *.o
15
+ *.a
16
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rails_zen.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Vysakh Sreenivasan
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,102 @@
1
+ # RailsZen
2
+
3
+ **AIM**: To save time by giving a boilerplate, and a thought flow.
4
+
5
+ A step by step generator. This will get *uniqueness*, *validations* from you, and write
6
+ the appropriate files (model, migration, model_spec).
7
+
8
+ The specs generated here assumes you are using
9
+
10
+ - Rspec (>3.0)
11
+ - Shoulda matchers
12
+ - FactoryGirl
13
+
14
+ *NOTE*: You need to use this app at the root of your rails directory
15
+
16
+ *Disclamier*: Things like mocks, stubs and proper testing might not be possible with this project.
17
+ The aim is to automate as many things as possible, this is not a panacea :) .
18
+
19
+ ## Installation
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ ```ruby
24
+ gem 'rails_zen'
25
+ ```
26
+
27
+ And then execute:
28
+
29
+ $ bundle
30
+
31
+ Or install it yourself as:
32
+
33
+ $ gem install rails_zen
34
+
35
+ ## Usage
36
+
37
+ ### COMMANDS
38
+
39
+ #### model g (generate)
40
+
41
+ rails_zen model g user name:string score:integer
42
+
43
+ - Once you enter this command, you will have few questions asked such as what to validate, which attribute is unique.
44
+ - Based on your input, the model, model_spec and migration files will be written
45
+
46
+ #### model act (action)
47
+
48
+ rails_zen model act calculator sum
49
+
50
+ - When you want to add a method to your model, you could invoke this command.
51
+
52
+ - This will get inputs from you such as:
53
+ - what the method does
54
+ - the argument names
55
+ - sample argument with a corresponding output
56
+
57
+ - Based on these input, a skeleton method will be written to your model file and model spec file
58
+
59
+ *OPTIONS*: If you want to write a class method you can pass --class option like this
60
+
61
+
62
+ rails_zen model g calculator sum --class
63
+
64
+ #### Use help to see the examples
65
+
66
+ rails_zen model g help
67
+ rails_zen model act help
68
+
69
+ You could see this sample video demonstrating the usage of the gem.
70
+
71
+ [![Rails_zen](https://i.ytimg.com/vi/rXphSHFXT1M/0.jpg)](http://youtu.be/rXphSHFXT1M)
72
+
73
+ ### Tip
74
+
75
+ - Create aliases for these commands in your bashrc or zshrc.
76
+ - I'm using
77
+
78
+ alias rzmg="rails_zen model g "
79
+ alias rzma="rails_zen model act "
80
+
81
+ ```bash
82
+ rzmg user name:string score:integer
83
+ rzma user calculate_score
84
+ ```
85
+ ## Contributing
86
+
87
+ 1. Fork it ( https://github.com/[my-github-username]/rails_zen/fork )
88
+
89
+ bundle binstub rspec-core
90
+ bundle binstub cucumber
91
+
92
+ bin/rspec
93
+ bin/cucumber
94
+
95
+ - This project uses [thor](https://github.com/erikhuda/thor/). You could [refer this blog post](willschenk.com/making-a-command-line-utility-with-gems-and-thor/) to get a quick idea.
96
+ - To read the source code, start with `lib/cli.rb` & `bin/rails_zen`
97
+
98
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
99
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
100
+ 4. Push to the branch (`git push origin my-new-feature`)
101
+ 5. Please write unit test using rspec and integeration spec using aruba/cucumber.
102
+ 6. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ # If you want to make this the default task
7
+ task :default => :spec
8
+
data/bin/rails_zen ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rails_zen'
4
+ RailsZen::Dexterity.start( ARGV )
@@ -0,0 +1,49 @@
1
+ Feature: Create a function & related spec for the model
2
+
3
+ Scenario: Enters the command with arguments
4
+ When I run `rails_zen model act calculator sum` interactively
5
+ When I close the stdin stream
6
+ Then the output should contain "What does your method do?"
7
+
8
+ Scenario: Enters what the method does
9
+ When I run `rails_zen model act calculator sum` interactively
10
+ And I type "returns sum of two numbers"
11
+ #And I type "a,b"
12
+ #And I type "1,2"
13
+ #And I type "3"
14
+ When I close the stdin stream
15
+ Then the output should contain "What name would you give your arguments"
16
+
17
+ Scenario: Enters the argument names
18
+ When I run `rails_zen model act calculator sum` interactively
19
+ And I type "returns sum of two numbers"
20
+ And I type "a,b"
21
+ #And I type "1,2"
22
+ #And I type "3"
23
+ When I close the stdin stream
24
+ Then the output should contain "Give example arguments"
25
+
26
+ Scenario: Enters the argument values
27
+ When I run `rails_zen model act calculator sum` interactively
28
+ And I type "returns sum of two numbers"
29
+ And I type "a,b"
30
+ And I type "1,2"
31
+ #And I type "3"
32
+ When I close the stdin stream
33
+ Then the output should contain "Enter the expected output for the previously entered arguments. eg: 3"
34
+
35
+ Scenario: Enters no arguments
36
+ When I run `rails_zen model act greet hello` interactively
37
+ And I type "says hello"
38
+ And I type ""
39
+ When I close the stdin stream
40
+ Then the output should not contain "Give example arguments"
41
+
42
+ #@focus
43
+ #Scenario: Enters the end result
44
+ #When I run `rails_zen model act user sum` interactively
45
+ #And I type "returns sum of two numbers"
46
+ #And I type "a,b"
47
+ #And I type "1,2"
48
+ #And I type "3"
49
+ #Then For this user model, the exit status should be 0
@@ -0,0 +1,64 @@
1
+ Feature: Generate model related things
2
+
3
+ Scenario: Enters the command with arguments
4
+ When I run `rails_zen model g user name:string` interactively
5
+ And I type "0"
6
+ When I close the stdin stream
7
+ Then the output should contain "0 name"
8
+
9
+ Scenario: Selects simple attributes
10
+ When I run `rails_zen model g user name:string phone:integer` interactively
11
+ And I type "0"
12
+ And I type "n"
13
+ When I close the stdin stream
14
+ Then the output should contain "Should :phone be present always in your record?"
15
+
16
+ Scenario: No unique attributes and integer
17
+ When I run `rails_zen model g user name:string phone:integer` interactively
18
+ And I type "0"
19
+ And I type "n"
20
+ And I type " "
21
+ When I close the stdin stream
22
+ Then the output should contain "phone is an integer do you want to check"
23
+
24
+ Scenario: No unique attributes, integer and has a relation
25
+ When I run `rails_zen model g user name:string` interactively
26
+ And I type "0"
27
+ And I type "n"
28
+ And I type "posts"
29
+ When I close the stdin stream
30
+ #Then the exit status should be 0
31
+ Then the output should contain "Do you have any has_many relations?"
32
+
33
+ #@focus
34
+ # file writing part
35
+ #Scenario: No unique attributes, integer and has a relation
36
+ #When I run `rails_zen model g user name:string phone:integer` interactively
37
+ #And I type "1"
38
+ #And I type "n"
39
+ #And I type "posts"
40
+ #Then the exit status should be 0
41
+
42
+
43
+ Scenario: No unique attributes and string
44
+ When I run `rails_zen model g user name:string phone:integer` interactively
45
+ And I type "1"
46
+ And I type "n"
47
+ And I type " "
48
+ Then the exit status should be 0
49
+
50
+ Scenario: not a unique attribute and a relation
51
+ When I run `rails_zen model g user name:string phone:integer location:belongs_to` interactively
52
+ And I type "0,1"
53
+ And I type "y"
54
+ Given I have all files
55
+ And I type "0"
56
+ Then the output should contain "0 if it is not unique"
57
+
58
+ Scenario: unique attribute is a relation
59
+ When I run `rails_zen model g user name:string phone:integer location:belongs_to` interactively
60
+ And I type "0,1"
61
+ And I type "y"
62
+ Given I have all files
63
+ And I type "1"
64
+ Then the output should contain "0 if it is not unique"
@@ -0,0 +1,18 @@
1
+ require 'rails_zen/write_to_files/write_to_model'
2
+
3
+ Then /^For this (\w+) model, the exit status should be (\d+)$/ do |model, exit_status|
4
+ #File.open("app/models/#{model}.rb", 'w+') {|f| f.write("class #{model.capitalize} < ActiveRecord::Base\nend\n") }
5
+ assert_exit_status(exit_status.to_i)
6
+ end
7
+
8
+ Given /I have all files/ do
9
+ file = String.new("class User < ActiveRecord::Base\nend\n")
10
+ loc = double('file')
11
+
12
+ allow(File).to receive(:open).with(any_args) { loc }
13
+ allow(File).to receive(:binread).with(any_args) { file }
14
+
15
+ allow_any_instance_of(RailsZen::WriteToModel).to receive(:file_name) { '/randompath/yo'}
16
+
17
+ allow(Dir).to receive(:glob).with(any_args) {["2023_create_users.rb"]}
18
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ require 'aruba/cucumber'
3
+ require 'fileutils'
4
+ require 'rspec/expectations'
5
+ require 'cucumber/rspec/doubles'
6
+
7
+ Before do
8
+ @aruba_timeout_seconds = 5
9
+ end
data/lib/cli.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'thor'
2
+ require 'cli/model'
3
+
4
+ module RailsZen
5
+ class Dexterity < Thor
6
+
7
+ desc "model COMMANDS", "Generator related to Rails modules"
8
+ subcommand "model", RailsZen::CLI::Model
9
+ end
10
+ end
data/lib/cli/model.rb ADDED
@@ -0,0 +1,33 @@
1
+ require "rails_zen/given_model_gen"
2
+ require "rails_zen/model_action"
3
+
4
+ module RailsZen
5
+ module CLI
6
+ class Model < Thor
7
+ desc "g MODELNAME ATTRIBUTES", "generate model, migration, spec files and step & step validations"
8
+ long_desc %{
9
+
10
+ Eg: rails_zen g model user name:string email:string score:integer
11
+
12
+ The command generates the usual model, migration and model_spec files. After that,
13
+ things we manually add such as validation or uniqueness are interactively asked by
14
+ this command to write into model, migration and spec file.
15
+
16
+
17
+ }
18
+ def g(model_name, *attrs)
19
+ attrs = attrs.join(' ')
20
+ system("rails g model #{model_name} #{attrs}")
21
+ RailsZen::GivenModelGen.new(model_name, attrs).step_by_step
22
+
23
+ #check_has_many
24
+ end
25
+
26
+ desc "act MODELNAME NAME ", "create an actions and action spec for a model"
27
+ option :class
28
+ def act(model_name, action_name)
29
+ RailsZen::ModelAction.new(action_name, options[:class], model_name).write!
30
+ end
31
+ end
32
+ end
33
+ end
data/lib/rails_zen.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "rails_zen/version"
2
+ require "cli"
3
+
4
+ module RailsZen
5
+ end
@@ -0,0 +1,89 @@
1
+ require 'stringio'
2
+ require 'highline/import'
3
+
4
+ module RailsZen
5
+ class ChosenAttr
6
+ attr_accessor :name, :type, :validator, :type_based_validators, :scope_attr
7
+
8
+ def initialize(name, type)
9
+ @name = name
10
+ @type = type
11
+ @scope_attr = []
12
+ end
13
+ def get_user_inputs
14
+ get_presence_req
15
+ get_type_based_validations
16
+ end
17
+
18
+ def get_presence_req
19
+ say "\n\nShould :#{name} be present always in your record?\n"
20
+ say"--------------------------------------------------------------"
21
+ inp = agree("Reply with y or n")
22
+
23
+ if inp
24
+ @validator = "validates_presence_of"
25
+ #say "What should be the default value? If there is no default value enter n"
26
+ #val = $stdin.gets.strip
27
+ #if val != 'n'
28
+ #@default_value = val
29
+ #end
30
+ get_uniqueness_req
31
+ else
32
+ @validator = nil
33
+ end
34
+ end
35
+
36
+ def get_uniqueness_req
37
+ say "Should :#{name} be an unique column?\n"
38
+ say "-------------------------------------\n\n"
39
+ say "Reply with \n
40
+ 0 if it is not unique \n
41
+ 1 if it is just unique \n
42
+ 2 if it is unique with respect to another attr \n\n"
43
+
44
+ inp = ask("Please enter", Integer) { |q| q.in = 0..2 }
45
+
46
+ if inp == 2
47
+ #say "Setting presence true in your models and migrations"
48
+ say "\n#{name} is unique along with ?\n Reply with attr name\n "
49
+
50
+ if is_relation?
51
+ @scope_attr << "#{name}_id" unless name.end_with? "_id"
52
+ end
53
+
54
+ say("if it is a relation reply along with id: eg: user_id \n\n $->")
55
+ @scope_attr << ask("Enter (comma sep list) ", lambda { |str| str.split(/,\s*/) })
56
+ @scope_attr = @scope_attr.flatten.map(&:to_sym)
57
+
58
+ @validator = "validates_uniqueness_scoped_to"
59
+ elsif inp == 1
60
+ @validator = "validates_uniqueness_of"
61
+ end
62
+ end
63
+
64
+ def get_type_based_validations
65
+ if(type == "integer" || type == "decimal")
66
+ @validator_line = "#@validator_line, numericality: true"
67
+
68
+ say "#{name} is an integer do you want to check \n
69
+ 1 just the numericality? \n
70
+ 2 check if it is only integer\n\n $->
71
+ "
72
+ input = ask("Please enter", Integer) { |q| q.in = 1..2}
73
+
74
+ map_input = {
75
+ 1 => "validate_numericality", 2 => "validate_integer"
76
+ #"3" => "validate_greater_than", "4" => "validate_lesser_than"
77
+ }
78
+
79
+ @type_based_validators = map_input[input]
80
+
81
+ elsif(is_relation?)
82
+ @type_based_validators = "validate_belongs_to"
83
+ end
84
+ end
85
+ def is_relation?
86
+ type =="belongs_to" || type == "references" || (type.end_with? "_id")
87
+ end
88
+ end
89
+ end