dtf 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -1
- data/.travis.yml +7 -2
- data/Gemfile +3 -2
- data/README.md +105 -6
- data/Rakefile +2 -0
- data/app/models/analysis_case.rb +1 -1
- data/app/models/case_test.rb +1 -1
- data/app/models/user.rb +3 -2
- data/app/models/verification_suite.rb +1 -1
- data/bin/dtf +23 -20
- data/db/seeds.rb +4 -0
- data/doc/AnalysisCase.html +123 -0
- data/doc/CaseTest.html +123 -0
- data/doc/Dtf.html +129 -0
- data/doc/Dtf/DtfCommands.html +471 -0
- data/doc/User.html +123 -0
- data/doc/VerificationSuite.html +123 -0
- data/doc/_index.html +171 -0
- data/doc/class_list.html +53 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +328 -0
- data/doc/file.README.html +256 -0
- data/doc/file_list.html +55 -0
- data/doc/frames.html +28 -0
- data/doc/index.html +256 -0
- data/doc/js/app.js +214 -0
- data/doc/js/full_list.js +173 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +100 -0
- data/doc/top-level-namespace.html +274 -0
- data/dtf.gemspec +3 -1
- data/lib/config/environment.rb +1 -1
- data/lib/dtf.rb +85 -2
- data/lib/dtf/dtf_error_system.rb +16 -0
- data/lib/dtf/dtf_help_system.rb +55 -0
- data/lib/dtf/version.rb +2 -2
- data/lib/tasks/setup.thor +5 -3
- data/spec/acceptance/create_basic_associations.feature +13 -0
- data/spec/acceptance/implement_help_system.feature +16 -0
- data/spec/fabricators/analysis_case_fabricator.rb +1 -1
- data/spec/fabricators/case_test_fabricator.rb +1 -1
- data/spec/fabricators/user_fabricator.rb +4 -4
- data/spec/fabricators/verification_suite_fabricator.rb +1 -1
- data/spec/models/analysis_case_spec.rb +53 -11
- data/spec/models/case_test_spec.rb +57 -11
- data/spec/models/user_spec.rb +46 -11
- data/spec/models/verification_suite_spec.rb +52 -12
- data/spec/spec_helper.rb +21 -1
- data/spec/steps/feature_steps.rb +14 -12
- data/spec/support/custom_matchers/model_steps.rb +17 -18
- metadata +77 -18
- data/bin/dtf-create_user +0 -11
- data/bin/dtf-create_vs +0 -10
- data/bin/dtf-delete_user +0 -18
- data/bin/dtf-delete_vs +0 -14
- data/bin/dtf-setup +0 -7
- data/spec/acceptance/0001_create_basic_models.feature +0 -9
- data/spec/acceptance/0002_create_basic_associations.feature +0 -11
- data/spec/acceptance/0003_execute_help_switch.feature +0 -7
data/dtf.gemspec
CHANGED
@@ -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
|
data/lib/config/environment.rb
CHANGED
data/lib/dtf.rb
CHANGED
@@ -1,7 +1,90 @@
|
|
1
|
-
#
|
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
|
-
|
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
|
data/lib/dtf/version.rb
CHANGED
data/lib/tasks/setup.thor
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
1
3
|
class DtfSetup < Thor
|
2
4
|
|
3
|
-
desc "install", "
|
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 "
|
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]", "
|
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,8 +1,8 @@
|
|
1
|
-
#
|
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,21 +1,63 @@
|
|
1
|
-
#
|
1
|
+
# encoding: UTF-8
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe "
|
5
|
+
describe "AnalysisCase" do
|
6
6
|
|
7
|
-
|
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
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
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
|
-
#
|
1
|
+
# encoding: UTF-8
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe "
|
5
|
+
describe "CaseTest" do
|
6
6
|
|
7
|
-
|
8
|
-
puts Benchmark.measure { let (:case_test) { Fabricate(:case_test) } }
|
7
|
+
context "when instantiated" do
|
9
8
|
|
10
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
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
|
data/spec/models/user_spec.rb
CHANGED
@@ -1,21 +1,56 @@
|
|
1
|
-
#
|
1
|
+
# encoding: UTF-8
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
|
-
require 'benchmark'
|
5
4
|
|
6
5
|
describe "User" do
|
7
6
|
|
8
|
-
|
9
|
-
puts Benchmark.measure { let (:user) { Fabricate(:user) } }
|
7
|
+
context "when instantiated" do
|
10
8
|
|
11
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
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
|