dtf 0.2.2 → 0.2.3

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.
Files changed (60) hide show
  1. data/.rspec +1 -1
  2. data/.travis.yml +7 -2
  3. data/Gemfile +3 -2
  4. data/README.md +105 -6
  5. data/Rakefile +2 -0
  6. data/app/models/analysis_case.rb +1 -1
  7. data/app/models/case_test.rb +1 -1
  8. data/app/models/user.rb +3 -2
  9. data/app/models/verification_suite.rb +1 -1
  10. data/bin/dtf +23 -20
  11. data/db/seeds.rb +4 -0
  12. data/doc/AnalysisCase.html +123 -0
  13. data/doc/CaseTest.html +123 -0
  14. data/doc/Dtf.html +129 -0
  15. data/doc/Dtf/DtfCommands.html +471 -0
  16. data/doc/User.html +123 -0
  17. data/doc/VerificationSuite.html +123 -0
  18. data/doc/_index.html +171 -0
  19. data/doc/class_list.html +53 -0
  20. data/doc/css/common.css +1 -0
  21. data/doc/css/full_list.css +57 -0
  22. data/doc/css/style.css +328 -0
  23. data/doc/file.README.html +256 -0
  24. data/doc/file_list.html +55 -0
  25. data/doc/frames.html +28 -0
  26. data/doc/index.html +256 -0
  27. data/doc/js/app.js +214 -0
  28. data/doc/js/full_list.js +173 -0
  29. data/doc/js/jquery.js +4 -0
  30. data/doc/method_list.html +100 -0
  31. data/doc/top-level-namespace.html +274 -0
  32. data/dtf.gemspec +3 -1
  33. data/lib/config/environment.rb +1 -1
  34. data/lib/dtf.rb +85 -2
  35. data/lib/dtf/dtf_error_system.rb +16 -0
  36. data/lib/dtf/dtf_help_system.rb +55 -0
  37. data/lib/dtf/version.rb +2 -2
  38. data/lib/tasks/setup.thor +5 -3
  39. data/spec/acceptance/create_basic_associations.feature +13 -0
  40. data/spec/acceptance/implement_help_system.feature +16 -0
  41. data/spec/fabricators/analysis_case_fabricator.rb +1 -1
  42. data/spec/fabricators/case_test_fabricator.rb +1 -1
  43. data/spec/fabricators/user_fabricator.rb +4 -4
  44. data/spec/fabricators/verification_suite_fabricator.rb +1 -1
  45. data/spec/models/analysis_case_spec.rb +53 -11
  46. data/spec/models/case_test_spec.rb +57 -11
  47. data/spec/models/user_spec.rb +46 -11
  48. data/spec/models/verification_suite_spec.rb +52 -12
  49. data/spec/spec_helper.rb +21 -1
  50. data/spec/steps/feature_steps.rb +14 -12
  51. data/spec/support/custom_matchers/model_steps.rb +17 -18
  52. metadata +77 -18
  53. data/bin/dtf-create_user +0 -11
  54. data/bin/dtf-create_vs +0 -10
  55. data/bin/dtf-delete_user +0 -18
  56. data/bin/dtf-delete_vs +0 -14
  57. data/bin/dtf-setup +0 -7
  58. data/spec/acceptance/0001_create_basic_models.feature +0 -9
  59. data/spec/acceptance/0002_create_basic_associations.feature +0 -11
  60. data/spec/acceptance/0003_execute_help_switch.feature +0 -7
@@ -27,10 +27,12 @@ Gem::Specification.new do |gem|
27
27
  gem.add_dependency "json"
28
28
  gem.add_dependency "json_pure"
29
29
  gem.add_dependency "standalone_migrations"
30
+ gem.add_dependency "trollop" # This implements the help system
30
31
 
31
32
  gem.add_development_dependency "turnip"
32
33
  gem.add_development_dependency "rspec", [">=2.10.0"]
33
34
  gem.add_development_dependency "fabrication"
34
35
  gem.add_development_dependency "vcr"
35
-
36
+ gem.add_development_dependency "yard" # For generating documentation
37
+ gem.add_development_dependency "redcarpet" # For generating YARD docs
36
38
  end
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # encoding: UTF-8
2
2
 
3
3
  # Application wide requirements
4
4
  require 'active_record'
data/lib/dtf.rb CHANGED
@@ -1,7 +1,90 @@
1
- # -*- coding: UTF-8 -*-
1
+ # encoding: UTF-8
2
2
 
3
3
  require "dtf/version"
4
4
 
5
5
  module Dtf
6
6
  load "#{File.join(File.dirname(__FILE__), "/config/environment.rb")}"
7
- end
7
+
8
+ class DtfCommands
9
+ def self.create_user(cmd_opts)
10
+ if [:user_name_given, :full_name_given, :email_address_given].all? { |sym| cmd_opts.key?(sym) } then
11
+ user = User.where(user_name: cmd_opts[:user_name],
12
+ full_name: cmd_opts[:full_name],
13
+ email_address: cmd_opts[:email_address]).first_or_create
14
+
15
+ # Check to make sure user was actually saved to the db
16
+ if user.persisted? then
17
+ puts "Created user \'#{cmd_opts[:user_name]}\' for \'#{cmd_opts[:full_name]}\'"
18
+ else
19
+ # Oops, it wasn't! Notify user and display any error message(s)
20
+ $stderr.puts "ERROR: #{cmd_opts[:user_name].to_s} was NOT created! Please fix the following errors and try again:"
21
+ user.errors.messages.keys.each do |key|
22
+ $stderr.puts "#{key.to_s.capitalize.gsub('_', ' ').to_s} #{user.errors.messages[key][0].to_s}!"
23
+ end
24
+ # Now throw a proper error code to the system, while exiting the script
25
+ abort()
26
+ end
27
+ else
28
+ raise_error # This error here is thrown when not all params are provided
29
+ end
30
+ end
31
+
32
+ def self.delete_user(cmd, cmd_opts)
33
+ if [:user_name_given, :delete_all].all? { |sym| cmd_opts.key?(sym) } then
34
+ # NOTE: :delete_all is 'true' by default. passing '--no-delete-all' sets it to false,
35
+ # and adds the :delete_all_given key to the cmd_opts hash, set to true.
36
+ # This means NOT to delete all VSs associated with this user. We delete them by default.
37
+ if cmd_opts[:delete_all] == false && cmd_opts[:delete_all_given] == true
38
+ puts "#{cmd} called with '--no-delete-all' set! NOT deleting all owned VSs!"
39
+ puts "Reassigning VSs to Library. New owner will be \'Library Owner\'"
40
+ user = User.find_by_user_name(cmd_opts[:user_name])
41
+ lib_owner = User.find_by_user_name("library_owner")
42
+ user.verification_suites.all.each do |vs|
43
+ vs.user_id = lib_owner.id
44
+ vs.save
45
+ end
46
+ User.delete(user)
47
+ else
48
+ puts "#{cmd} called with '--delete-all' set or on by default! Deleting all VSs owned by #{cmd_opts[:user_name]}"
49
+ user = User.find_by_user_name(cmd_opts[:user_name])
50
+ user.verification_suites.all.each do |vs|
51
+ VerificationSuite.delete(vs)
52
+ end
53
+ if user.verification_suites.empty? then
54
+ User.delete(user)
55
+ end
56
+ end
57
+ else
58
+ raise_error
59
+ end
60
+ end
61
+
62
+ def self.create_vs(cmd_opts)
63
+ if [:user_name_given, :name_given].all? { |sym| cmd_opts.key?(sym) } then
64
+ user = User.find_by_user_name(cmd_opts[:user_name])
65
+ vs = user.verification_suites.create(name: cmd_opts[:name], description: cmd_opts[:description])
66
+ if vs.persisted? then
67
+ puts "VS named \'#{cmd_opts[:name]}\' allocated to user \'#{cmd_opts[:user_name]}\'"
68
+ else
69
+ $stderr.puts "ERROR: Failed to save Verification Suite. Check DB logfile for errors"
70
+ abort()
71
+ end
72
+ else
73
+ raise_error
74
+ end
75
+ end
76
+
77
+ def self.delete_vs(cmd, cmd_opts)
78
+ if [:user_name_given, :id_given].all? { |sym| cmd_opts.key?(sym) } then
79
+ puts "#{cmd} called! Deleting #{cmd_opts[:user_name]}\'s VS with ID \'#{cmd_opts[:id]}\'"
80
+ user = User.find_by_user_name(cmd_opts[:user_name])
81
+ vs = user.verification_suites.find(cmd_opts[:id])
82
+ VerificationSuite.delete(vs)
83
+ else
84
+ raise_error
85
+ end
86
+ end
87
+
88
+ end # End of class
89
+
90
+ end # End of module
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+ # Reusable error response method
3
+ def raise_error
4
+ raise ArgumentError
5
+ rescue
6
+ $stderr.puts "ERROR! #{@cmd} did not receive all required options."
7
+ $stderr.puts "See 'dtf #{@cmd} -h' for help with this sub-command"
8
+
9
+ # Set non-zero exit value on error, for scripting use.
10
+ abort()
11
+ end
12
+
13
+ def display_errors()
14
+ # TODO: Refactor error display to take sub-command as an arg
15
+ # and display obj.errors.messages.each properly for each arg type.
16
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: UTF-8
2
+ # DTF Help System
3
+ require 'trollop' # Used to implement help system
4
+
5
+ SUB_COMMANDS = %w(create_user delete_user create_vs delete_vs)
6
+
7
+ # Global options default to '--version|-v' and '--help|-h'
8
+ global_opts = Trollop::options do
9
+ version "DTF v#{Dtf::VERSION}"
10
+ banner <<-EOS
11
+ #{version}
12
+ (c) Copyright 2012 David Deryl Downey / Deryl R. Doucette. All Rights Reserved.
13
+ This is free software; see the LICENSE file for copying conditions.
14
+ There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
+
16
+ Usage:
17
+ dtf -v|--version -h|--help [[sub_cmds <options>] -h|--help]
18
+
19
+ Valid [sub_cmds] are: create_(user|vs), delete_(user|vs)
20
+ See 'dtf [sub_cmd] -h' for each sub_cmd's details and options
21
+
22
+ EOS
23
+ stop_on SUB_COMMANDS
24
+ end
25
+
26
+ # Sub-commands go here
27
+ @cmd = ARGV.shift
28
+ @cmd_opts = case @cmd
29
+ when "create_user"
30
+ Trollop::options do
31
+ opt(:user_name, desc="Username for new TF user - REQUIRED", opts={:type => :string, :short => '-u'})
32
+ opt(:full_name, desc="Real name for new TF user - REQUIRED", opts={:type => :string, :short => '-n'})
33
+ opt(:email_address, desc="Email address for new TF user - REQUIRED", opts={:type => :string, :short => '-e'})
34
+ end
35
+ when "create_vs"
36
+ Trollop::options do
37
+ opt(:user_name, desc="TF user to associate this VS with - REQUIRED", opts={:type => :string, :short => '-u'})
38
+ opt(:name, desc="Name for new VS - REQUIRED", opts={:type => :string, :short => '-n'})
39
+ opt(:description, desc="Description of VS's intended use - OPTIONAL", opts={:type => :string, :short => '-d', :default => ''})
40
+ end
41
+ when "delete_user"
42
+ Trollop::options do
43
+ opt(:user_name, desc="Username of TF user to delete - REQUIRED", opts={:type => :string, :short => '-u'})
44
+ opt(:delete_all, desc="Delete _all_ VSs this user owns", :type => :flag, :default => true)
45
+ end
46
+ when "delete_vs"
47
+ Trollop::options do
48
+ opt(:user_name, desc="Username of VS owner - REQUIRED", opts={:type => :string, :short => '-u'})
49
+ opt(:id, desc="ID of VS to be deleted - REQUIRED", opts={:type => :int, :short => '-i'})
50
+ end
51
+ when nil
52
+ Trollop::die "No command specified! Please specify an applicable command"
53
+ else
54
+ Trollop::die "Unknown DTF sub-command: #{cmd.inspect}"
55
+ end
@@ -1,5 +1,5 @@
1
- # -*- coding: UTF-8 -*-
1
+ # encoding: UTF-8
2
2
 
3
3
  module Dtf
4
- VERSION = "0.2.2"
4
+ VERSION = "0.2.3"
5
5
  end
@@ -1,9 +1,11 @@
1
+ # encoding: UTF-8
2
+
1
3
  class DtfSetup < Thor
2
4
 
3
- desc "install", "installs database schemas and control scripts"
5
+ desc "install", "Installs database migrations, the main schema, and configuration files"
4
6
  method_options :force => :boolean
5
7
  def install(name= "*")
6
- puts "installing db schemas and control scripts"
8
+ puts "Installing db migrations, main schema, and config files"
7
9
 
8
10
  # The gem is installed elsewhere so the copy path needs to be
9
11
  # relative to the gem, not the user.
@@ -25,7 +27,7 @@ class DtfSetup < Thor
25
27
  end
26
28
  end
27
29
 
28
- desc "config [NAME]", "copy db configuration file(s)"
30
+ desc "config [NAME]", "Copy db configuration file(s)"
29
31
  method_options :force => :boolean
30
32
  def config(name = "*")
31
33
 
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ Feature: Verification of User associations
4
+ Background:
5
+ Given a User
6
+
7
+ Scenario: User should own Verification Suites
8
+ When I create a Verification Suite
9
+ Then I should own a Verification Suite
10
+
11
+ Scenario: User should own Analysis Cases
12
+ When I create an Analysis Case
13
+ Then I should own an Analysis Case
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+
3
+ Feature: DTF Help System is correctly implemented
4
+ Background:
5
+ Given I have dtf installed
6
+
7
+ Scenario Outline: Sub-command specific help is received
8
+ Given I request help for sub-command <sub_cmd>
9
+ Then I should see <help_response> in the response
10
+
11
+ Examples:
12
+ | sub_cmd | help_response |
13
+ | create_user | --email |
14
+ | delete_user | --delete-all |
15
+ | create_vs | --name |
16
+ | delete_vs | --id |
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # encoding: UTF-8
2
2
 
3
3
  Fabricator(:analysis_case) do
4
4
  name "DTF Analysis Case"
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # encoding: UTF-8
2
2
 
3
3
  Fabricator(:case_test) do
4
4
  description "Fabricated CT for DTF testing"
@@ -1,8 +1,8 @@
1
- # -*- coding: UTF-8 -*-
1
+ # encoding: UTF-8
2
2
 
3
3
  Fabricator(:user) do
4
- full_name "John Q Public"
5
- email_address "jqp@public.com"
6
- user_name "johnpublic"
4
+ full_name { sequence(:num, 5 ) { |num| "John Q Public #{num}" } }
5
+ email_address { sequence(:email_address, 5) { |num| "jqp#{num}@public.com" } }
6
+ user_name { sequence(:user_name, 5) { |num| "johnpublic#{num}" } }
7
7
  end
8
8
 
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # encoding: UTF-8
2
2
 
3
3
  Fabricator(:verification_suite) do
4
4
  name "DTF Verification Suite"
@@ -1,21 +1,63 @@
1
- # -*- coding: UTF-8 -*-
1
+ # encoding: UTF-8
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe "Analysis Case" do
5
+ describe "AnalysisCase" do
6
6
 
7
- puts "Analysis Case Benchmark"
8
- puts Benchmark.measure { let (:analysis_case) { Fabricate(:analysis_case) } }
7
+ context "when instantiated" do
9
8
 
9
+ let(:analysis_case) { AnalysisCase.new }
10
+
11
+ it "should be the proper class" do
12
+ analysis_case.should be_a(AnalysisCase)
13
+ end
14
+
15
+ it "should be invalid without being assigned to a verification suite" do
16
+ analysis_case.should_not be_valid
17
+ analysis_case[:verification_suite_id].should be_nil
18
+ analysis_case.new_record?.should be_true
19
+ end
20
+
21
+ it "should be invalid without a name" do
22
+ analysis_case.should_not be_valid
23
+ analysis_case.errors.messages[:name].should eq(["can't be blank"])
24
+ analysis_case.new_record?.should be_true
25
+ end
26
+
27
+ it "should be invalid without a description" do
28
+ analysis_case.should_not be_valid
29
+ analysis_case.errors.messages[:description].should eq(["can't be blank"])
30
+ analysis_case.new_record?.should be_true
31
+ end
10
32
 
11
- let(:analysis_case) { Fabricate(:analysis_case) }
33
+ it "should not be saved" do
34
+ analysis_case.new_record?.should be_true
35
+ analysis_case.persisted?.should_not be_true
36
+ end
12
37
 
13
- it "should be created/fabricated" do
14
- analysis_case.should be_a(AnalysisCase)
15
- end
38
+ end
39
+
40
+ context "when created" do
41
+ user = Fabricate(:user)
42
+ vs = user.verification_suites.create(name: "RSpec Test VS", description: "Bogus VS for RSpec")
43
+ analysis_case = vs.analysis_cases.create(name: "RSpec Test AC", description: "Bogus AC for RSpec")
44
+
45
+ it "should be owned by a verification suite" do
46
+ analysis_case.should be_valid
47
+ analysis_case.verification_suite_id.should_not be_nil
48
+ end
16
49
 
17
- it "should be persisted" do
18
- analysis_case.save
19
- analysis_case.persisted?
50
+ it "should have a valid name and description" do
51
+ analysis_case.should be_valid
52
+ analysis_case.errors.messages.should be_empty
53
+ analysis_case.name.should_not be_nil
54
+ analysis_case.description.should_not be_nil
55
+ end
56
+
57
+ it "should be saved" do
58
+ analysis_case.should be_valid
59
+ analysis_case.new_record?.should_not be_true
60
+ analysis_case.persisted?.should be_true
61
+ end
20
62
  end
21
63
  end
@@ -1,20 +1,66 @@
1
- # -*- coding: UTF-8 -*-
1
+ # encoding: UTF-8
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe "Case Test" do
5
+ describe "CaseTest" do
6
6
 
7
- puts "Case Test Benchmark"
8
- puts Benchmark.measure { let (:case_test) { Fabricate(:case_test) } }
7
+ context "when instantiated" do
9
8
 
10
- let(:case_test) { Fabricate(:case_test) }
9
+ let(:case_test) { CaseTest.new }
10
+
11
+ it "should be the proper class" do
12
+ case_test.should be_a(CaseTest)
13
+ end
14
+
15
+ it "should be invalid without being assigned to a analysis case" do
16
+ case_test.should_not be_valid
17
+ case_test[:analysis_case_id].should be_nil
18
+ case_test.new_record?.should be_true
19
+ end
20
+
21
+ it "should be invalid without a cmd" do
22
+ case_test.should_not be_valid
23
+ case_test.errors.messages[:cmd].should eq(["can't be blank"])
24
+ case_test.new_record?.should be_true
25
+ end
26
+
27
+ it "should be invalid without a description" do
28
+ case_test.should_not be_valid
29
+ case_test.errors.messages[:description].should eq(["can't be blank"])
30
+ case_test.new_record?.should be_true
31
+ end
11
32
 
12
- it "should be created/fabricated" do
13
- case_test.should be_a(CaseTest)
14
- end
33
+ it "should not be saved" do
34
+ case_test.new_record?.should be_true
35
+ case_test.persisted?.should_not be_true
36
+ end
37
+
38
+ end
39
+
40
+ context "when created" do
41
+ user = Fabricate(:user)
42
+ vs = user.verification_suites.create(name: "RSpec Test VS", description: "Bogus VS for RSpec")
43
+ analysis_case = vs.analysis_cases.create(name: "RSpec Test AC", description: "Bogus AC for RSpec")
44
+ case_test = analysis_case.case_tests.create(cmd: "bundle exec rspec spec",
45
+ description: "Bogus CT for RSpec"
46
+ )
47
+
48
+ it "should be owned by an analysis case" do
49
+ case_test.should be_valid
50
+ case_test.analysis_case_id.should_not be_nil
51
+ end
15
52
 
16
- it "should be persisted" do
17
- case_test.save
18
- case_test.persisted?
53
+ it "should have a valid cmd and description" do
54
+ case_test.should be_valid
55
+ case_test.errors.messages.should be_empty
56
+ case_test.cmd.should_not be_nil
57
+ case_test.description.should_not be_nil
58
+ end
59
+
60
+ it "should be saved" do
61
+ case_test.should be_valid
62
+ case_test.new_record?.should_not be_true
63
+ case_test.persisted?.should be_true
64
+ end
19
65
  end
20
66
  end
@@ -1,21 +1,56 @@
1
- # -*- coding: UTF-8 -*-
1
+ # encoding: UTF-8
2
2
 
3
3
  require 'spec_helper'
4
- require 'benchmark'
5
4
 
6
5
  describe "User" do
7
6
 
8
- puts "User Benchmark"
9
- puts Benchmark.measure { let (:user) { Fabricate(:user) } }
7
+ context "when instantiated" do
10
8
 
11
- let (:user) { Fabricate(:user) }
9
+ let(:user) { User.new }
10
+
11
+ it "should be the proper class" do
12
+ user.should be_a(User)
13
+ end
12
14
 
13
- it "should be created/fabricated" do
14
- user.should be_a(User)
15
- end
15
+ it "should be invalid without a user_name" do
16
+ user.should_not be_valid
17
+ user.errors.messages[:user_name].should eq(["can't be blank"])
18
+ user.new_record?.should be_true
19
+ end
20
+
21
+ it "should be invalid without an email_address" do
22
+ user.should_not be_valid
23
+ user.errors.messages[:email_address].should eq(["can't be blank"])
24
+ user.new_record?.should be_true
25
+ end
26
+
27
+ it "should be invalid without a full_name" do
28
+ user.should_not be_valid
29
+ user.errors.messages[:full_name].should eq(["can't be blank"])
30
+ user.new_record?.should be_true
31
+ end
32
+
33
+ it "should not be saved" do
34
+ user.new_record?.should be_true
35
+ user.persisted?.should_not be_true
36
+ end
16
37
 
17
- it "should be persisted" do
18
- user.save
19
- user.persisted?
38
+ end
39
+
40
+ context "when created" do
41
+ let(:user) { Fabricate(:user)}
42
+
43
+ it "should have a valid user_name, full_name, and email_address" do
44
+ user.should be_valid
45
+ user.errors.messages.should be_empty
46
+ user.user_name.should_not be_nil
47
+ user.full_name.should_not be_nil
48
+ user.email_address.should_not be_nil
49
+ end
50
+
51
+ it "should be saved" do
52
+ user.new_record?.should_not be_true
53
+ user.persisted?.should be_true
54
+ end
20
55
  end
21
56
  end