chemistrykit 3.7.0 → 3.8.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.
- data/.rubocop.yml +6 -0
- data/CHANGELOG.md +21 -0
- data/Gemfile +13 -0
- data/Guardfile +9 -0
- data/README.md +59 -2
- data/Rakefile +34 -6
- data/chemistrykit.gemspec +3 -11
- data/exceptions.reek +3 -0
- data/features/chemists.feature +123 -0
- data/features/new.feature +2 -0
- data/lib/chemistrykit/chemist.rb +34 -0
- data/lib/chemistrykit/chemist/repository/csv_chemist_repository.rb +79 -0
- data/lib/chemistrykit/cli/cli.rb +14 -9
- data/lib/chemistrykit/configuration.rb +2 -2
- data/lib/chemistrykit/formula/chemist_aware.rb +10 -0
- data/lib/chemistrykit/formula/formula_lab.rb +99 -0
- data/lib/chemistrykit/parallel_tests_mods.rb +1 -1
- data/lib/templates/chemistrykit/chemists/chemists.csv +1 -0
- data/lib/templates/formula.tt +2 -0
- data/spec/integration/lib/chemistrykit/formula/formula_lab_spec.rb +59 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/bad_chemists.csv +3 -0
- data/spec/support/chemists.csv +6 -0
- data/spec/support/default_chemists.csv +1 -0
- data/spec/support/formulas/sub_module/basic_formula.rb +13 -0
- data/spec/support/formulas/sub_module/chemist_formula.rb +15 -0
- data/spec/support/keyless_chemists.csv +3 -0
- data/spec/support/other_chemists.csv +2 -0
- data/spec/unit/lib/chemistrykit/chemist/repository/csv_chemist_repository_spec.rb +99 -0
- data/spec/unit/lib/chemistrykit/chemist_spec.rb +43 -0
- data/spec/unit/lib/chemistrykit/formula/chemist_aware_spec.rb +25 -0
- data/spec/unit/lib/chemistrykit/formula/formula_lab_spec.rb +63 -0
- metadata +39 -119
data/lib/chemistrykit/cli/cli.rb
CHANGED
@@ -9,6 +9,8 @@ require 'chemistrykit/cli/beaker'
|
|
9
9
|
require 'chemistrykit/cli/helpers/formula_loader'
|
10
10
|
require 'chemistrykit/catalyst'
|
11
11
|
require 'chemistrykit/formula/base'
|
12
|
+
require 'chemistrykit/formula/formula_lab'
|
13
|
+
require 'chemistrykit/chemist/repository/csv_chemist_repository'
|
12
14
|
require 'selenium_connect'
|
13
15
|
require 'chemistrykit/configuration'
|
14
16
|
require 'parallel_tests'
|
@@ -60,7 +62,7 @@ module ChemistryKit
|
|
60
62
|
method_option :params, type: :hash
|
61
63
|
method_option :tag, type: :array
|
62
64
|
method_option :config, default: 'config.yaml', aliases: '-c', desc: 'Supply alternative config file.'
|
63
|
-
# TODO there should be a facility to simply pass a path to this command
|
65
|
+
# TODO: there should be a facility to simply pass a path to this command
|
64
66
|
method_option :beakers, aliases: '-b', type: :array
|
65
67
|
# This is set if the thread is being run in parallel so as not to trigger recursive concurency
|
66
68
|
method_option :parallel, default: false
|
@@ -70,7 +72,7 @@ module ChemistryKit
|
|
70
72
|
|
71
73
|
def brew
|
72
74
|
config = load_config options['config']
|
73
|
-
# TODO perhaps the params should be rolled into the available
|
75
|
+
# TODO: perhaps the params should be rolled into the available
|
74
76
|
# config object injected into the system?
|
75
77
|
pass_params if options['params']
|
76
78
|
|
@@ -116,13 +118,9 @@ module ChemistryKit
|
|
116
118
|
protected
|
117
119
|
|
118
120
|
def override_configs(options, config)
|
119
|
-
# TODO expand this to allow for more overrides as needed
|
120
|
-
if options['results_file']
|
121
|
-
|
122
|
-
end
|
123
|
-
if options['retry']
|
124
|
-
config.retries_on_failure = options['retry'].to_i
|
125
|
-
end
|
121
|
+
# TODO: expand this to allow for more overrides as needed
|
122
|
+
config.log.results_file = options['results_file'] if options['results_file']
|
123
|
+
config.retries_on_failure = options['retry'].to_i if options['retry']
|
126
124
|
config
|
127
125
|
end
|
128
126
|
|
@@ -188,6 +186,13 @@ module ChemistryKit
|
|
188
186
|
@sc = SeleniumConnect.start configuration
|
189
187
|
@job = @sc.create_job # create a new job
|
190
188
|
@driver = @job.start name: test_name
|
189
|
+
|
190
|
+
# TODO: this is messy, and could be refactored out into a static on the lab
|
191
|
+
chemist_data_paths = Dir.glob(File.join(Dir.getwd, 'chemists', '*.csv'))
|
192
|
+
repo = ChemistryKit::Chemist::Repository::CsvChemistRepository.new chemist_data_paths
|
193
|
+
# make the formula lab available
|
194
|
+
@formula_lab = ChemistryKit::Formula::FormulaLab.new @driver, repo, File.join(Dir.getwd, 'formulas')
|
195
|
+
|
191
196
|
example.run
|
192
197
|
end
|
193
198
|
c.after(:each) do
|
@@ -48,7 +48,7 @@ module ChemistryKit
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def self.initialize_with_yaml(file)
|
51
|
-
|
51
|
+
new symbolize_keys YAML.load_file file
|
52
52
|
end
|
53
53
|
|
54
54
|
private
|
@@ -56,7 +56,7 @@ module ChemistryKit
|
|
56
56
|
def populate_with_hash(hash)
|
57
57
|
hash.each do |key, value|
|
58
58
|
begin
|
59
|
-
|
59
|
+
send "#{key}=", value unless value.nil?
|
60
60
|
rescue NoMethodError
|
61
61
|
raise ArgumentError.new "The config key: \"#{key}\" is unknown!"
|
62
62
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
|
3
|
+
require 'find'
|
4
|
+
|
5
|
+
module ChemistryKit
|
6
|
+
module Formula
|
7
|
+
# Factory class to assemble page objects with users
|
8
|
+
class FormulaLab
|
9
|
+
|
10
|
+
attr_reader :formula
|
11
|
+
|
12
|
+
def initialize(driver, chemist_repository, formulas_dir)
|
13
|
+
@driver = driver
|
14
|
+
@chemist_repository = chemist_repository
|
15
|
+
raise ArgumentError, "Formula directory \"#{formulas_dir}\" does not exist!" unless File.directory?(formulas_dir)
|
16
|
+
@formulas_dir = formulas_dir
|
17
|
+
end
|
18
|
+
|
19
|
+
def using(formula_key)
|
20
|
+
@formula = formula_key
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def mix(formula_key = nil)
|
25
|
+
@formula = formula_key ||= formula
|
26
|
+
raise ArgumentError, 'A formula key must be defined!' unless @formula
|
27
|
+
formula_file = find_formula_file
|
28
|
+
class_name = get_class_name formula_file
|
29
|
+
formula = constantize(class_name).new(@driver)
|
30
|
+
if formula.singleton_class.include?(ChemistryKit::Formula::ChemistAware)
|
31
|
+
raise RuntimeError, "Trying to mix a formula: \"#{formula_key}\" that requires a user, but no user set!" unless @chemist
|
32
|
+
formula.chemist = @chemist
|
33
|
+
end
|
34
|
+
formula
|
35
|
+
end
|
36
|
+
|
37
|
+
def with(key)
|
38
|
+
@chemist = @chemist_repository.load_chemist_by_key key
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def with_random(type)
|
43
|
+
@chemist = @chemist_repository.load_random_chemist_of_type type
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def with_first(type)
|
48
|
+
@chemist = @chemist_repository.load_first_chemist_of_type type
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def find_formula_file
|
55
|
+
Find.find(@formulas_dir) do |path|
|
56
|
+
return path if path =~ /.*#{@formula}\.rb$/
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# TODO: try to resolve this backreff thing
|
61
|
+
# rubocop:disable AvoidPerlBackrefs
|
62
|
+
def get_class_name(formula_file)
|
63
|
+
string = formula_file.match(/(#{@formulas_dir.split('/').last}.*#{@formula})\.rb$/)[1]
|
64
|
+
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
|
65
|
+
string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub('/', '::')
|
66
|
+
end
|
67
|
+
# rubocop:enable AvoidPerlBackrefs
|
68
|
+
|
69
|
+
# "borrowed" from http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-constantize
|
70
|
+
# TODO: this could be simplified, refactored out, or just use the activestate module some how
|
71
|
+
def constantize(camel_cased_word)
|
72
|
+
names = camel_cased_word.split('::')
|
73
|
+
names.shift if names.empty? || names.first.empty?
|
74
|
+
|
75
|
+
names.reduce(Object) do |constant, name|
|
76
|
+
if constant == Object
|
77
|
+
constant.const_get(name)
|
78
|
+
else
|
79
|
+
candidate = constant.const_get(name)
|
80
|
+
next candidate if constant.const_defined?(name, false)
|
81
|
+
next candidate unless Object.const_defined?(name)
|
82
|
+
|
83
|
+
# Go down the ancestors to check it it's owned
|
84
|
+
# directly before we reach Object or the end of ancestors.
|
85
|
+
constant = constant.ancestors.reduce do |const, ancestor|
|
86
|
+
break const if ancestor == Object
|
87
|
+
break ancestor if ancestor.const_defined?(name, false)
|
88
|
+
const
|
89
|
+
end
|
90
|
+
|
91
|
+
# owner is in Object, so raise
|
92
|
+
constant.const_get(name, false)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
key,type
|
data/lib/templates/formula.tt
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'chemistrykit/formula/formula_lab'
|
5
|
+
require 'chemistrykit/chemist/repository/csv_chemist_repository'
|
6
|
+
|
7
|
+
describe ChemistryKit::Formula::FormulaLab do
|
8
|
+
|
9
|
+
VALID_CHEMIST_KEY = 'admin1'
|
10
|
+
VALID_CHEMIST_TYPE = 'admin'
|
11
|
+
|
12
|
+
VALID_BASIC_FORMULA_KEY = 'basic_formula'
|
13
|
+
VALID_CHEMIST_FORMULA_KEY = 'chemist_formula'
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
@stub_driver = double 'Selenium::WebDriver::Driver'
|
17
|
+
chemists_path = File.join(Dir.pwd, 'spec', 'support', 'chemists.csv')
|
18
|
+
@repo = ChemistryKit::Chemist::Repository::CsvChemistRepository.new chemists_path
|
19
|
+
formulas_dir = File.join(Dir.pwd, 'spec', 'support', 'formulas')
|
20
|
+
@lab = ChemistryKit::Formula::FormulaLab.new @stub_driver, @repo, formulas_dir
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should mix a formula without a chemist' do
|
24
|
+
formula = @lab.mix(VALID_BASIC_FORMULA_KEY)
|
25
|
+
formula.should be_an_instance_of Formulas::SubModule::BasicFormula
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should mix a formula with a chemist the standard way' do
|
29
|
+
formula = @lab.using(VALID_CHEMIST_FORMULA_KEY).with(VALID_CHEMIST_KEY).mix
|
30
|
+
formula.should be_an_instance_of Formulas::SubModule::ChemistFormula
|
31
|
+
formula.chemist.key.should eq VALID_CHEMIST_KEY
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should raise an error if trying to mix a formula that requires a user, without setting one' do
|
35
|
+
expect do
|
36
|
+
@lab.using(VALID_CHEMIST_FORMULA_KEY).mix
|
37
|
+
end.to raise_error RuntimeError, "Trying to mix a formula: \"#{VALID_CHEMIST_FORMULA_KEY}\" that requires a user, but no user set!"
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should mix a formula in the oposite way' do
|
41
|
+
formula = @lab.with(VALID_CHEMIST_KEY).mix(VALID_CHEMIST_FORMULA_KEY)
|
42
|
+
formula.should be_an_instance_of Formulas::SubModule::ChemistFormula
|
43
|
+
formula.chemist.key.should eq VALID_CHEMIST_KEY
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should mix a formula with a typed chemist' do
|
47
|
+
formula = @lab.with_first(VALID_CHEMIST_TYPE).mix(VALID_CHEMIST_FORMULA_KEY)
|
48
|
+
formula.should be_an_instance_of Formulas::SubModule::ChemistFormula
|
49
|
+
formula.chemist.key.should eq VALID_CHEMIST_KEY
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should mix a formula with a random chemist of a type' do
|
53
|
+
formula = @lab.with_random('random').mix(VALID_CHEMIST_FORMULA_KEY)
|
54
|
+
formula.should be_an_instance_of Formulas::SubModule::ChemistFormula
|
55
|
+
key = formula.chemist.key
|
56
|
+
(key == 'ran1' || key == 'ran2').should be_true
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -19,6 +19,9 @@ require_relative '../lib/chemistrykit/formula/base'
|
|
19
19
|
require_relative '../lib/chemistrykit/catalyst'
|
20
20
|
require_relative '../lib/chemistrykit/configuration'
|
21
21
|
|
22
|
+
require_relative '../spec/support/formulas/sub_module/basic_formula'
|
23
|
+
require_relative '../spec/support/formulas/sub_module/chemist_formula'
|
24
|
+
|
22
25
|
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
23
26
|
SimpleCov::Formatter::HTMLFormatter,
|
24
27
|
Coveralls::SimpleCov::Formatter
|
@@ -0,0 +1,6 @@
|
|
1
|
+
Key,Type,Email,Name,Password
|
2
|
+
admin1,admin,admin@email.com,Mr. Admin,abc123$
|
3
|
+
normal1,normal,normal@email.com,Ms. Normal,test123%
|
4
|
+
ran1,random,normal@email.com,Ms. Normal,test123%
|
5
|
+
ran2,random,normal@email.com,Ms. Normal,test123%
|
6
|
+
uuid_chemist,normal,normal{{UUID}}@email.com,Mr. uuid,test123#
|
@@ -0,0 +1 @@
|
|
1
|
+
key,type
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
|
3
|
+
require 'chemistrykit/formula/base'
|
4
|
+
require 'chemistrykit/formula/chemist_aware'
|
5
|
+
|
6
|
+
module Formulas
|
7
|
+
module SubModule
|
8
|
+
class ChemistFormula < ChemistryKit::Formula::Base
|
9
|
+
include ChemistryKit::Formula::ChemistAware
|
10
|
+
def open(url)
|
11
|
+
@driver.get url
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'chemistrykit/chemist/repository/csv_chemist_repository'
|
5
|
+
|
6
|
+
describe ChemistryKit::Chemist::Repository::CsvChemistRepository do
|
7
|
+
|
8
|
+
VALID_CHEMIST_CSV = 'chemists.csv'
|
9
|
+
VALID_DEFAULT_CSV = 'default_chemists.csv'
|
10
|
+
BAD_CHEMIST_CSV = 'bad_chemists.csv'
|
11
|
+
KEYLESS_CHEMIST_CSV = 'keyless_chemists.csv'
|
12
|
+
INVALID_CHEMIST_CSV = 'file_does_not_exist.csv'
|
13
|
+
VALID_USER_TYPE = 'admin'
|
14
|
+
VALID_USER_KEY = 'admin1'
|
15
|
+
INVALID_USER_TYPE = 'no_type'
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
csv_file = File.join(Dir.pwd, 'spec', 'support', VALID_CHEMIST_CSV)
|
19
|
+
@repo = ChemistryKit::Chemist::Repository::CsvChemistRepository.new(csv_file)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should be instantiated with a csv file path' do
|
23
|
+
@repo.should be_an_instance_of ChemistryKit::Chemist::Repository::CsvChemistRepository
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should raise and error if the file does not exist' do
|
27
|
+
expect do
|
28
|
+
csv_file = File.join(Dir.pwd, 'spec', 'support', INVALID_CHEMIST_CSV)
|
29
|
+
ChemistryKit::Chemist::Repository::CsvChemistRepository.new(csv_file)
|
30
|
+
end.to raise_error ArgumentError, 'Supplied file does not exist!'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should load a random by type identifier' do
|
34
|
+
chemist = @repo.load_first_chemist_of_type VALID_USER_TYPE
|
35
|
+
chemist.type.should eq VALID_USER_TYPE
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should load a random by specific key' do
|
39
|
+
chemist = @repo.load_chemist_by_key VALID_USER_KEY
|
40
|
+
chemist.key.should eq VALID_USER_KEY
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should load a random chemist by type' do
|
44
|
+
chemist = @repo.load_random_chemist_of_type 'random'
|
45
|
+
(chemist.key == 'ran1' || chemist.key == 'ran2').should be_true
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should set all the parameters defined in the csv file' do
|
49
|
+
chemist = @repo.load_first_chemist_of_type VALID_USER_TYPE
|
50
|
+
chemist.name.should eq 'Mr. Admin'
|
51
|
+
chemist.email.should eq 'admin@email.com'
|
52
|
+
chemist.password.should eq 'abc123$'
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should rais and error if the chemist is not found' do
|
56
|
+
expect do
|
57
|
+
@repo.load_first_chemist_of_type INVALID_USER_TYPE
|
58
|
+
end.to raise_error ArgumentError, 'Chemist for type "no_type" not found!'
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should raise and error if there is no type heading in the csv file' do
|
62
|
+
csv_file = File.join(Dir.pwd, 'spec', 'support', BAD_CHEMIST_CSV)
|
63
|
+
expect do
|
64
|
+
ChemistryKit::Chemist::Repository::CsvChemistRepository.new(csv_file)
|
65
|
+
end.to raise_error ArgumentError, 'You must define a type field!'
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should raise and error if there is no key heading in the csv file' do
|
69
|
+
csv_file = File.join(Dir.pwd, 'spec', 'support', KEYLESS_CHEMIST_CSV)
|
70
|
+
expect do
|
71
|
+
ChemistryKit::Chemist::Repository::CsvChemistRepository.new(csv_file)
|
72
|
+
end.to raise_error ArgumentError, 'You must define a key field!'
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'can search more than one csv file' do
|
76
|
+
files = []
|
77
|
+
files.push File.join(Dir.pwd, 'spec', 'support', VALID_CHEMIST_CSV)
|
78
|
+
files.push File.join(Dir.pwd, 'spec', 'support', 'other_chemists.csv')
|
79
|
+
repo = ChemistryKit::Chemist::Repository::CsvChemistRepository.new(files)
|
80
|
+
|
81
|
+
chemist = repo.load_first_chemist_of_type 'cowboy'
|
82
|
+
chemist.passion.should eq 'Wrasslin'
|
83
|
+
|
84
|
+
chemist = repo.load_first_chemist_of_type 'normal'
|
85
|
+
chemist.email = 'normal@email.com'
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should replace the {{UUID}} token with a uuid on runtime if found in a parameter' do
|
89
|
+
chemist = @repo.load_chemist_by_key 'uuid_chemist'
|
90
|
+
# the {{UUID}} token was placed in the email parameter
|
91
|
+
expect(chemist.email).to match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should not raise any error if there were no modifications to the default chemists file' do
|
95
|
+
csv_file = File.join(Dir.pwd, 'spec', 'support', VALID_DEFAULT_CSV)
|
96
|
+
repo = ChemistryKit::Chemist::Repository::CsvChemistRepository.new(csv_file)
|
97
|
+
repo.should be_an_instance_of ChemistryKit::Chemist::Repository::CsvChemistRepository
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'chemistrykit/chemist'
|
5
|
+
|
6
|
+
describe ChemistryKit::Chemist do
|
7
|
+
|
8
|
+
VALID_KEY = 'specific_admin'
|
9
|
+
VALID_TYPE = 'admin'
|
10
|
+
VALID_VALUE = 'my value'
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
@chemist = ChemistryKit::Chemist.new(VALID_KEY, VALID_TYPE)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'must have at least a key and type' do
|
17
|
+
@chemist.key.should eq VALID_KEY
|
18
|
+
@chemist.type.should eq VALID_TYPE
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should be able to set and get arbitrary data' do
|
22
|
+
@chemist.my_key = VALID_VALUE
|
23
|
+
@chemist.my_key.should eq VALID_VALUE
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should be able to get a hash of its data' do
|
27
|
+
@chemist.my_key = VALID_VALUE
|
28
|
+
@chemist.data.should eq my_key: VALID_VALUE
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should not be able to override the other instance variables' do
|
32
|
+
@chemist.type = 'other'
|
33
|
+
@chemist.type.should eq VALID_TYPE
|
34
|
+
@chemist.data.include?(:type).should be_false
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should be able to be populated with a hash of arbitrary data' do
|
38
|
+
dataset = { name: 'cool dude', email: 'fun@gmail.com', password: 'Oa8w*#)asd' }
|
39
|
+
@chemist.data = dataset
|
40
|
+
@chemist.name.should eq 'cool dude'
|
41
|
+
@chemist.email.should eq 'fun@gmail.com'
|
42
|
+
end
|
43
|
+
end
|