rails_zen 0.1.0

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: 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