cukedep 0.1.10 → 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG.md +4 -0
- data/Rakefile +4 -6
- data/lib/cukedep/application.rb +89 -91
- data/lib/cukedep/cli/cmd-line.rb +0 -7
- data/lib/cukedep/config.rb +70 -74
- data/lib/cukedep/constants.rb +1 -1
- data/lib/cukedep/cuke-runner.rb +0 -5
- data/lib/cukedep/customization.rb +0 -5
- data/lib/cukedep/feature-model.rb +1 -7
- data/lib/cukedep/feature-rep.rb +0 -4
- data/lib/cukedep/file-action.rb +209 -221
- data/lib/cukedep/gherkin-facade.rb +7 -10
- data/lib/cukedep/gherkin-listener.rb +82 -89
- data/lib/cukedep/hook-dsl.rb +0 -4
- data/lib/cukedep/sandbox.rb +0 -5
- data/sample/features/step_definitions/steps.rb +30 -26
- data/sample/features/support/env.rb +1 -1
- data/sample/model/model.rb +198 -205
- data/sample/result.html +1 -1
- data/spec/cukedep/application_spec.rb +15 -16
- data/spec/cukedep/cli/cmd-line_spec.rb +13 -16
- data/spec/cukedep/cuke-runner_spec.rb +55 -61
- data/spec/cukedep/customization_spec.rb +21 -26
- data/spec/cukedep/debug-file-action.rb +12 -10
- data/spec/cukedep/feature-model_spec.rb +13 -16
- data/spec/cukedep/feature-rep_spec.rb +4 -7
- data/spec/cukedep/file-action_spec.rb +18 -34
- data/spec/cukedep/file-parsing.rb +9 -11
- data/spec/cukedep/gherkin-facade_spec.rb +3 -8
- data/spec/cukedep/gherkin-listener_spec.rb +10 -12
- data/spec/cukedep/hook-dsl_spec.rb +6 -9
- data/spec/cukedep/sample_features/cukedep.rake +44 -37
- data/spec/cukedep/sample_features/cukedep_hooks.rb +2 -2
- data/spec/cukedep/sample_features/dependencies.dot +1 -1
- data/templates/rake.erb +36 -29
- metadata +2 -2
@@ -4,25 +4,24 @@ require 'gherkin'
|
|
4
4
|
require 'gherkin/lexer/encoding'
|
5
5
|
|
6
6
|
module Cukedep # This module is used as a namespace
|
7
|
-
|
8
7
|
# Facade design pattern: A facade is an object that provides
|
9
8
|
# a simplified interface to a larger body of code.
|
10
9
|
# Here the GherkinFacade class provides basic parsing service.
|
11
10
|
class GherkinFacade
|
12
11
|
# Indicate whether the parsing must be verbose or silent
|
13
12
|
attr_reader(:verbose)
|
14
|
-
|
13
|
+
|
15
14
|
# (External) encoding of the feature files.
|
16
15
|
# It is a string that represents the name of an encoding
|
17
16
|
# as expected by the mode argument of the IO#new method
|
18
17
|
attr_reader(:external_encoding)
|
19
|
-
|
18
|
+
|
20
19
|
|
21
20
|
def initialize(isVerbose, anExternalEncoding)
|
22
21
|
@verbose = isVerbose
|
23
22
|
@external_encoding = anExternalEncoding
|
24
23
|
end
|
25
|
-
|
24
|
+
|
26
25
|
# Parse feature files from the work directory that match
|
27
26
|
# one of the given file name patterns.
|
28
27
|
# Parse events are sent to the passed listener object.
|
@@ -34,22 +33,20 @@ module Cukedep # This module is used as a namespace
|
|
34
33
|
# List all .feature files in work directory that match the pattern
|
35
34
|
filenames = []
|
36
35
|
file_patterns.each { |patt| filenames.concat(Dir.glob(patt)) }
|
37
|
-
|
36
|
+
|
38
37
|
# Parse them
|
39
38
|
filenames.each do |fname|
|
40
39
|
puts " #{fname}" if verbose
|
41
40
|
# To prevent encoding issue, open the file
|
42
41
|
# with an explicit external encoding
|
43
|
-
File.open(fname, "r:#{external_encoding}") do |f|
|
44
|
-
parser.parse(f.read, fname, 0)
|
42
|
+
File.open(fname, "r:#{external_encoding}") do |f|
|
43
|
+
parser.parse(f.read, fname, 0)
|
45
44
|
end
|
46
45
|
end
|
47
|
-
|
46
|
+
|
48
47
|
return aListener
|
49
48
|
end
|
50
|
-
|
51
49
|
end # class
|
52
|
-
|
53
50
|
end # module
|
54
51
|
|
55
52
|
# End of file
|
@@ -4,95 +4,88 @@ require_relative 'feature-rep'
|
|
4
4
|
|
5
5
|
|
6
6
|
module Cukedep # This module is used as a namespace
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
90
|
-
|
91
|
-
end # class
|
92
|
-
|
7
|
+
class FeatureFileRep
|
8
|
+
attr_reader(:filepath)
|
9
|
+
attr(:feature, true)
|
10
|
+
|
11
|
+
def initialize(aFilepath)
|
12
|
+
@filepath = aFilepath
|
13
|
+
end
|
14
|
+
|
15
|
+
def basename()
|
16
|
+
File.basename(filepath)
|
17
|
+
end
|
18
|
+
end # class
|
19
|
+
|
20
|
+
# A ParserListener listens to all the formatting events
|
21
|
+
# emitted by the Gherkin parser.
|
22
|
+
# It converts the received the feature file elements and builds
|
23
|
+
# a representation of the feature files that is appropriate
|
24
|
+
# for the Cukedep application.
|
25
|
+
class GherkinListener
|
26
|
+
# The list of feature files encountered so far
|
27
|
+
attr_reader(:feature_files)
|
28
|
+
|
29
|
+
# Internal representation of the feature being parsed
|
30
|
+
attr(:current_feature, true)
|
31
|
+
|
32
|
+
def initialize()
|
33
|
+
@feature_files = []
|
34
|
+
end
|
35
|
+
|
36
|
+
######################################
|
37
|
+
# Event listening methods
|
38
|
+
######################################
|
39
|
+
|
40
|
+
# Called when beginning the parsing of a feature file.
|
41
|
+
# featureURI: path + filename of feature file.
|
42
|
+
def uri(featureURI)
|
43
|
+
new_file = FeatureFileRep.new(featureURI)
|
44
|
+
feature_files << new_file
|
45
|
+
end
|
46
|
+
|
47
|
+
# aFeature is a Gherkin::Formatter::Model::Feature instance
|
48
|
+
def feature(aFeature)
|
49
|
+
tag_names = aFeature.tags.map(&:name)
|
50
|
+
@current_feature = feature_files.last.feature = FeatureRep.new(tag_names)
|
51
|
+
end
|
52
|
+
|
53
|
+
# aBackground is a Gherkin::Formatter::Model::Background instance
|
54
|
+
def background(_aBackground)
|
55
|
+
; # Do nothing
|
56
|
+
end
|
57
|
+
|
58
|
+
# aScenario is a Gherkin::Formatter::Model::Scenario instance
|
59
|
+
def scenario(_aScenario)
|
60
|
+
; # Do nothing
|
61
|
+
end
|
62
|
+
|
63
|
+
# aScenarioOutline is a Gherkin::Formatter::Model::ScenarioOutline instance
|
64
|
+
def scenario_outline(_aScenarioOutline)
|
65
|
+
; # Do nothing
|
66
|
+
end
|
67
|
+
|
68
|
+
# theExamples is a Gherkin::Formatter::Model::Examples instance
|
69
|
+
def examples(_theExamples)
|
70
|
+
; # Do nothing
|
71
|
+
end
|
72
|
+
|
73
|
+
# aStep is a Gherkin::Formatter::Model::Step instance
|
74
|
+
def step(_aStep)
|
75
|
+
; # Do nothing
|
76
|
+
end
|
77
|
+
|
78
|
+
# End of feature file notification.
|
79
|
+
def eof()
|
80
|
+
; # Do nothing
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
# Catch all method
|
85
|
+
def method_missing(message, *_args)
|
86
|
+
puts "Method #{message} is not implemented (yet)."
|
87
|
+
end
|
88
|
+
end # class
|
93
89
|
end # module
|
94
90
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
91
|
# End of file
|
data/lib/cukedep/hook-dsl.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
|
4
4
|
module Cukedep # Module used as a namespace
|
5
|
-
|
6
5
|
# Mix-in module that defines the DSL (Domain-Specific Language)
|
7
6
|
# for specifying Cukedep hooks.
|
8
7
|
# A hook is a custom code block that is executed when
|
@@ -74,9 +73,6 @@ module HookDSL
|
|
74
73
|
handler = hooks.nil? ? nil : hooks.fetch(aScope)
|
75
74
|
return handler
|
76
75
|
end
|
77
|
-
|
78
76
|
end # module
|
79
|
-
|
80
77
|
end # module
|
81
|
-
|
82
78
|
# End of file
|
data/lib/cukedep/sandbox.rb
CHANGED
@@ -2,10 +2,8 @@
|
|
2
2
|
|
3
3
|
|
4
4
|
module Cukedep # This module is used as a namespace
|
5
|
-
|
6
5
|
# A context in which hook block codes are run.
|
7
6
|
class Sandbox
|
8
|
-
|
9
7
|
attr_reader(:base_dir)
|
10
8
|
attr_reader(:proj_dir)
|
11
9
|
|
@@ -13,9 +11,6 @@ module Cukedep # This module is used as a namespace
|
|
13
11
|
@base_dir = theBaseDir.dup.freeze
|
14
12
|
@proj_dir = theProjectDir.dup.freeze
|
15
13
|
end
|
16
|
-
|
17
14
|
end # class
|
18
|
-
|
19
15
|
end # module
|
20
|
-
|
21
16
|
# End of file
|
@@ -1,50 +1,54 @@
|
|
1
1
|
# File: steps.rb
|
2
2
|
# Step definitions for a sample Cucumber application
|
3
3
|
|
4
|
+
def store()
|
5
|
+
$store
|
6
|
+
end
|
7
|
+
|
4
8
|
Given(/^the catalogue is empty$/) do
|
5
|
-
|
9
|
+
store.zap_catalogue!
|
6
10
|
end
|
7
11
|
|
8
12
|
Given(/^I add the video "(.*?)" to the catalogue$/) do |a_title|
|
9
|
-
|
13
|
+
store.add_video(a_title)
|
10
14
|
end
|
11
15
|
|
12
16
|
Then(/^I should see the video "(.*?)" as unknown$/) do |a_title|
|
13
|
-
expect(
|
17
|
+
expect(store.search_video(a_title)).to be_nil
|
14
18
|
end
|
15
19
|
|
16
20
|
Then(/^I should see the video "(.*?)" as (available)$/) do |a_title, a_state|
|
17
|
-
found_video =
|
21
|
+
found_video = store.search_video(a_title)
|
18
22
|
expect(found_video.state).to eq(a_state.to_sym)
|
19
23
|
end
|
20
24
|
|
21
25
|
When(/^I remove the video "(.*?)"$/) do |a_title|
|
22
|
-
found_video =
|
26
|
+
found_video = store.search_video(a_title)
|
23
27
|
expect(found_video).not_to be_nil
|
24
28
|
expect(found_video.state).to eq(:available)
|
25
|
-
|
29
|
+
store.remove_video(found_video)
|
26
30
|
end
|
27
31
|
|
28
32
|
Given(/^there is no member yet$/) do
|
29
|
-
|
33
|
+
store.send(:zap_members!) # Why is this method seen as private?
|
30
34
|
end
|
31
35
|
|
32
36
|
Then(/^I should see member "(.*?)" as unknown$/) do |member_name|
|
33
|
-
expect(
|
37
|
+
expect(store.search_member(member_name)).to be_nil
|
34
38
|
end
|
35
39
|
|
36
40
|
Then(/^I should see member "(.*?)" as registered$/) do |member_name|
|
37
|
-
expect(
|
41
|
+
expect(store.search_member(member_name)).not_to be_nil
|
38
42
|
puts "Member #{member_name} is registered."
|
39
43
|
end
|
40
44
|
|
41
45
|
Given(/^I subscribe "(.*?)"$/) do |member_name|
|
42
|
-
|
46
|
+
store.add_member(member_name)
|
43
47
|
end
|
44
48
|
|
45
49
|
|
46
50
|
Given(/^there is no registered user$/) do
|
47
|
-
|
51
|
+
store.zap_users!
|
48
52
|
end
|
49
53
|
|
50
54
|
When(/^I enter the credentials "(.*?)"$/) do |credential|
|
@@ -52,54 +56,54 @@ When(/^I enter the credentials "(.*?)"$/) do |credential|
|
|
52
56
|
end
|
53
57
|
|
54
58
|
Then(/^I should not be authorized$/) do
|
55
|
-
expect(
|
56
|
-
puts
|
59
|
+
expect(store.search_user(@entered_credential)).to be_nil
|
60
|
+
puts 'Invalid user credential'
|
57
61
|
end
|
58
62
|
|
59
63
|
When(/^I register my credentials "(.*?)"$/) do |credential|
|
60
|
-
|
64
|
+
store.add_user(credential)
|
61
65
|
end
|
62
66
|
|
63
67
|
Then(/^I should see a welcome message$/) do
|
64
|
-
expect(
|
65
|
-
puts
|
68
|
+
expect(store.search_user(@entered_credential)).not_to be_nil
|
69
|
+
puts 'Welcome to the rental application.'
|
66
70
|
end
|
67
71
|
|
68
72
|
|
69
73
|
When(/^I register the rental of "(.*?)" for "(.*?)"$/) do |a_title, member_name|
|
70
|
-
found_video =
|
74
|
+
found_video = store.search_video(a_title)
|
71
75
|
expect(found_video).not_to be_nil
|
72
76
|
expect(found_video.state).to eq(:available)
|
73
77
|
|
74
|
-
member =
|
78
|
+
member = store.search_member(member_name)
|
75
79
|
expect(member).not_to be_nil
|
76
|
-
|
80
|
+
store.add_rental(found_video, member)
|
77
81
|
@confirm_rental = true
|
78
82
|
end
|
79
83
|
|
80
84
|
Then(/^I should see the rental confirmed$/) do
|
81
|
-
puts
|
85
|
+
puts 'Rental registered.' if @confirm_rental
|
82
86
|
@confirm_rental = nil
|
83
87
|
end
|
84
88
|
|
85
89
|
Then(/^I should see the rental refused$/) do
|
86
|
-
puts
|
90
|
+
puts 'Rental refused.' unless @confirm_rental
|
87
91
|
end
|
88
92
|
|
89
93
|
|
90
|
-
When(/^I register the return of "(.*?)" from "(.*?)"$/) do |
|
91
|
-
rental =
|
94
|
+
When(/^I register the return of "(.*?)" from "(.*?)"$/) do |title, member_name|
|
95
|
+
rental = store.search_rental(title)
|
92
96
|
expect(rental).not_to be_nil
|
93
97
|
expect(rental.member).to eq(member_name)
|
94
|
-
|
98
|
+
store.close_rental(rental)
|
95
99
|
@confirm_return = true
|
96
100
|
end
|
97
101
|
|
98
102
|
Then(/^I should see the return confirmed$/) do
|
99
|
-
puts
|
103
|
+
puts 'Return registered.' if @confirm_return
|
100
104
|
@confirm_return = nil
|
101
105
|
end
|
102
106
|
|
103
107
|
|
104
108
|
|
105
|
-
# End of file
|
109
|
+
# End of file
|
data/sample/model/model.rb
CHANGED
@@ -1,216 +1,209 @@
|
|
1
1
|
# File: model.rb
|
2
2
|
|
3
3
|
require 'pp'
|
4
|
-
require 'yaml' # Rely on YAML for object persistence
|
4
|
+
require 'yaml' # Rely on YAML for object persistence
|
5
5
|
|
6
6
|
|
7
7
|
# Module used as a namespace
|
8
8
|
module Sample
|
9
|
+
# Assumption: the store has one examplar only of a video title
|
10
|
+
Video = Struct.new(
|
11
|
+
:title, # Title of the video (as an identifier)
|
12
|
+
:state # Current state of the video
|
13
|
+
)
|
14
|
+
|
15
|
+
# A member of the video store, i.e. a person that is allowed
|
16
|
+
# to rent a video from the store.
|
17
|
+
Member = Struct.new(
|
18
|
+
:name # As an identifier
|
19
|
+
)
|
20
|
+
|
21
|
+
# Association object between a Video and a Member.
|
22
|
+
# In our sample model, no rental history is performed
|
23
|
+
Rental = Struct.new(
|
24
|
+
:video, # Use the title of the rented video as key
|
25
|
+
:member # Use the name of the Member as key
|
26
|
+
)
|
27
|
+
|
28
|
+
# The identification of a store rental employee
|
29
|
+
# that is authorized to use the rental software.
|
30
|
+
User = Struct.new(
|
31
|
+
:credential # user credential
|
32
|
+
)
|
33
|
+
|
34
|
+
# Simplistic domain model of a video rental store.
|
35
|
+
class RentalStore
|
36
|
+
MyDir = File.dirname(__FILE__) + '/'
|
37
|
+
CatalogueFile = 'catalogue.yml'
|
38
|
+
MembersFile = 'members.yml'
|
39
|
+
RentalsFile = 'rentals.yml'
|
40
|
+
UsersFile = 'users.yml'
|
41
|
+
|
42
|
+
|
43
|
+
# The list of all videos owned by the store.
|
44
|
+
attr_reader(:catalogue)
|
45
|
+
|
46
|
+
# The list of all Members
|
47
|
+
attr_reader(:members)
|
48
|
+
|
49
|
+
# The list of all open-standing rentals
|
50
|
+
attr_reader(:rentals)
|
51
|
+
|
52
|
+
# The list of application user (credentials)
|
53
|
+
attr_reader(:users)
|
54
|
+
|
55
|
+
def initialize()
|
56
|
+
init_catalogue
|
57
|
+
init_members
|
58
|
+
init_rentals
|
59
|
+
init_users
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
# Clear the catalogue (= make it empty).
|
64
|
+
def zap_catalogue!()
|
65
|
+
catalogue.clear
|
66
|
+
save_catalogue
|
67
|
+
zap_rentals!
|
68
|
+
end
|
69
|
+
|
70
|
+
def zap_members!()
|
71
|
+
members.clear
|
72
|
+
save_members
|
73
|
+
zap_rentals!
|
74
|
+
end
|
75
|
+
|
76
|
+
def zap_users!()
|
77
|
+
users.clear
|
78
|
+
save_users
|
79
|
+
end
|
80
|
+
|
81
|
+
# Search a Video object having the given title
|
82
|
+
def search_video(aTitle)
|
83
|
+
result = catalogue.find { |video| video.title.strip == aTitle.strip }
|
84
|
+
if result.nil?
|
85
|
+
msg = "Video with title '#{aTitle}' isn't in the catalogue."
|
86
|
+
$stderr.puts msg
|
87
|
+
end
|
88
|
+
|
89
|
+
return result
|
90
|
+
end
|
91
|
+
|
92
|
+
def remove_video(aVideo)
|
93
|
+
catalogue.delete(aVideo)
|
94
|
+
save_catalogue
|
95
|
+
end
|
96
|
+
|
97
|
+
# Add a new video to the catalogue
|
98
|
+
def add_video(aTitle)
|
99
|
+
# Simplification: no check for title collision
|
100
|
+
catalogue << Video.new(aTitle, :available)
|
101
|
+
save_catalogue
|
102
|
+
end
|
103
|
+
|
104
|
+
def search_member(aName)
|
105
|
+
mb = members.find { |person| person.name.strip == aName.strip }
|
106
|
+
puts "No member with name #{aName}." if mb.nil?
|
107
|
+
|
108
|
+
return mb
|
109
|
+
end
|
9
110
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
:name # As an identifier
|
20
|
-
)
|
21
|
-
|
22
|
-
# Association object between a Video and a Member.
|
23
|
-
# In our sample model, no rental history is performed
|
24
|
-
Rental = Struct.new(
|
25
|
-
:video, # Use the title of the rented video as key
|
26
|
-
:member # Use the name of the Member as key
|
27
|
-
)
|
28
|
-
|
29
|
-
# The identification of a store rental employee
|
30
|
-
# that is authorized to use the rental software.
|
31
|
-
User = Struct.new(
|
32
|
-
:credential # user credential
|
33
|
-
)
|
34
|
-
|
35
|
-
# Simplistic domain model of a video rental store.
|
36
|
-
class RentalStore
|
37
|
-
MyDir = File.dirname(__FILE__) + '/'
|
38
|
-
CatalogueFile = 'catalogue.yml'
|
39
|
-
MembersFile = 'members.yml'
|
40
|
-
RentalsFile = 'rentals.yml'
|
41
|
-
UsersFile = 'users.yml'
|
42
|
-
|
43
|
-
|
44
|
-
# The list of all videos owned by the store.
|
45
|
-
attr_reader(:catalogue)
|
46
|
-
|
47
|
-
# The list of all Members
|
48
|
-
attr_reader(:members)
|
49
|
-
|
50
|
-
# The list of all open-standing rentals
|
51
|
-
attr_reader(:rentals)
|
52
|
-
|
53
|
-
# The list of application user (credentials)
|
54
|
-
attr_reader(:users)
|
55
|
-
|
56
|
-
def initialize()
|
57
|
-
init_catalogue()
|
58
|
-
init_members()
|
59
|
-
init_rentals()
|
60
|
-
init_users()
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
# Clear the catalogue (= make it empty).
|
65
|
-
def zap_catalogue!()
|
66
|
-
catalogue.clear()
|
67
|
-
save_catalogue()
|
68
|
-
zap_rentals!()
|
69
|
-
end
|
70
|
-
|
71
|
-
def zap_members!()
|
72
|
-
members.clear()
|
73
|
-
save_members()
|
74
|
-
zap_rentals!()
|
75
|
-
end
|
76
|
-
|
77
|
-
def zap_users!()
|
78
|
-
users.clear()
|
79
|
-
save_users()
|
80
|
-
end
|
81
|
-
|
82
|
-
# Search a Video object having the given title
|
83
|
-
def search_video(aTitle)
|
84
|
-
result = catalogue.find {|video| video.title.strip == aTitle.strip}
|
85
|
-
if result.nil?
|
86
|
-
msg = "Video with title '#{aTitle}' isn't in the catalogue."
|
87
|
-
$stderr.puts msg
|
88
|
-
end
|
89
|
-
|
90
|
-
return result
|
91
|
-
end
|
92
|
-
|
93
|
-
def remove_video(aVideo)
|
94
|
-
catalogue.delete(aVideo)
|
95
|
-
save_catalogue()
|
96
|
-
end
|
97
|
-
|
98
|
-
# Add a new video to the catalogue
|
99
|
-
def add_video(aTitle)
|
100
|
-
# Simplification: no check for title collision
|
101
|
-
catalogue << Video.new(aTitle, :available)
|
102
|
-
save_catalogue()
|
103
|
-
end
|
104
|
-
|
105
|
-
def search_member(aName)
|
106
|
-
mb = members.find {|person| person.name.strip == aName.strip}
|
107
|
-
puts "No member with name #{aName}." if mb.nil?
|
108
|
-
|
109
|
-
return mb
|
110
|
-
end
|
111
|
-
|
112
|
-
def add_member(aName)
|
113
|
-
# Simplification: no check for name collision
|
114
|
-
members << Member.new(aName)
|
115
|
-
save_members()
|
116
|
-
end
|
117
|
-
|
118
|
-
def search_user(aCredential)
|
119
|
-
users.find {|user| user.credential.strip == aCredential.strip}
|
120
|
-
end
|
121
|
-
|
122
|
-
def add_user(aCredential)
|
123
|
-
# Simplification: no check for credential collision
|
124
|
-
users << User.new(aCredential)
|
125
|
-
save_users()
|
126
|
-
end
|
127
|
-
|
128
|
-
def search_rental(aTitle)
|
129
|
-
rentals.find {|r| r.video.strip == aTitle.strip}
|
130
|
-
end
|
131
|
-
|
132
|
-
def add_rental(aVideo, aMember)
|
133
|
-
rentals << Rental.new(aVideo.title, aMember.name)
|
134
|
-
aVideo.state = :rented
|
135
|
-
save_rentals
|
136
|
-
end
|
137
|
-
|
138
|
-
def close_rental(aRental)
|
139
|
-
returned_video = search_video(aRental.video)
|
140
|
-
returned_video.state = :available
|
141
|
-
rentals.delete(aRental)
|
142
|
-
save_rentals
|
143
|
-
end
|
144
|
-
|
145
|
-
private
|
146
|
-
def init_catalogue()
|
147
|
-
filepath = MyDir + CatalogueFile
|
148
|
-
if File.exist?(filepath)
|
149
|
-
@catalogue = YAML.load_file(filepath)
|
150
|
-
else
|
151
|
-
@catalogue = []
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def init_members()
|
156
|
-
filepath = MyDir + MembersFile
|
157
|
-
if File.exist?(filepath)
|
158
|
-
@members = YAML.load_file(filepath)
|
159
|
-
else
|
160
|
-
@members = []
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
def init_users()
|
165
|
-
filepath = MyDir + UsersFile
|
166
|
-
if File.exist?(filepath)
|
167
|
-
@users = YAML.load_file(filepath)
|
168
|
-
else
|
169
|
-
@users = []
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
def init_rentals()
|
174
|
-
filepath = MyDir + RentalsFile
|
175
|
-
if File.exist?(filepath)
|
176
|
-
@rentals = YAML.load_file(filepath)
|
177
|
-
else
|
178
|
-
@rentals = []
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
def zap_rentals!()
|
183
|
-
rentals.clear
|
184
|
-
save_rentals()
|
185
|
-
end
|
186
|
-
|
187
|
-
def zap_members!()
|
188
|
-
members.clear
|
189
|
-
save_members()
|
190
|
-
end
|
191
|
-
|
192
|
-
def save_catalogue()
|
193
|
-
filepath = MyDir + CatalogueFile
|
194
|
-
File.open(filepath, 'w') {|f| YAML.dump(catalogue, f)}
|
195
|
-
end
|
196
|
-
|
197
|
-
def save_members()
|
198
|
-
filepath = MyDir + MembersFile
|
199
|
-
File.open(filepath, 'w') {|f| YAML.dump(members, f)}
|
200
|
-
end
|
201
|
-
|
202
|
-
def save_users()
|
203
|
-
filepath = MyDir + UsersFile
|
204
|
-
File.open(filepath, 'w') {|f| YAML.dump(users, f)}
|
205
|
-
end
|
206
|
-
|
207
|
-
def save_rentals()
|
208
|
-
filepath = MyDir + RentalsFile
|
209
|
-
File.open(filepath, 'w') {|f| YAML.dump(rentals, f)}
|
210
|
-
end
|
211
|
-
|
212
|
-
end # class
|
111
|
+
def add_member(aName)
|
112
|
+
# Simplification: no check for name collision
|
113
|
+
members << Member.new(aName)
|
114
|
+
save_members
|
115
|
+
end
|
116
|
+
|
117
|
+
def search_user(aCredential)
|
118
|
+
users.find { |user| user.credential.strip == aCredential.strip }
|
119
|
+
end
|
213
120
|
|
121
|
+
def add_user(aCredential)
|
122
|
+
# Simplification: no check for credential collision
|
123
|
+
users << User.new(aCredential)
|
124
|
+
save_users
|
125
|
+
end
|
126
|
+
|
127
|
+
def search_rental(aTitle)
|
128
|
+
rentals.find { |r| r.video.strip == aTitle.strip }
|
129
|
+
end
|
130
|
+
|
131
|
+
def add_rental(aVideo, aMember)
|
132
|
+
rentals << Rental.new(aVideo.title, aMember.name)
|
133
|
+
aVideo.state = :rented
|
134
|
+
save_rentals
|
135
|
+
end
|
136
|
+
|
137
|
+
def close_rental(aRental)
|
138
|
+
returned_video = search_video(aRental.video)
|
139
|
+
returned_video.state = :available
|
140
|
+
rentals.delete(aRental)
|
141
|
+
save_rentals
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def init_catalogue()
|
147
|
+
filepath = MyDir + CatalogueFile
|
148
|
+
if File.exist?(filepath)
|
149
|
+
@catalogue = YAML.load_file(filepath)
|
150
|
+
else
|
151
|
+
@catalogue = []
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def init_members()
|
156
|
+
filepath = MyDir + MembersFile
|
157
|
+
if File.exist?(filepath)
|
158
|
+
@members = YAML.load_file(filepath)
|
159
|
+
else
|
160
|
+
@members = []
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def init_users()
|
165
|
+
filepath = MyDir + UsersFile
|
166
|
+
if File.exist?(filepath)
|
167
|
+
@users = YAML.load_file(filepath)
|
168
|
+
else
|
169
|
+
@users = []
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def init_rentals()
|
174
|
+
filepath = MyDir + RentalsFile
|
175
|
+
if File.exist?(filepath)
|
176
|
+
@rentals = YAML.load_file(filepath)
|
177
|
+
else
|
178
|
+
@rentals = []
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def zap_rentals!()
|
183
|
+
rentals.clear
|
184
|
+
save_rentals
|
185
|
+
end
|
186
|
+
|
187
|
+
def save_catalogue()
|
188
|
+
filepath = MyDir + CatalogueFile
|
189
|
+
File.open(filepath, 'w') { |f| YAML.dump(catalogue, f) }
|
190
|
+
end
|
191
|
+
|
192
|
+
def save_members()
|
193
|
+
filepath = MyDir + MembersFile
|
194
|
+
File.open(filepath, 'w') { |f| YAML.dump(members, f) }
|
195
|
+
end
|
196
|
+
|
197
|
+
def save_users()
|
198
|
+
filepath = MyDir + UsersFile
|
199
|
+
File.open(filepath, 'w') { |f| YAML.dump(users, f) }
|
200
|
+
end
|
201
|
+
|
202
|
+
def save_rentals()
|
203
|
+
filepath = MyDir + RentalsFile
|
204
|
+
File.open(filepath, 'w') { |f| YAML.dump(rentals, f) }
|
205
|
+
end
|
206
|
+
end # class
|
214
207
|
end # module
|
215
208
|
|
216
|
-
# End of file
|
209
|
+
# End of file
|