csd 0.1.18 → 0.2.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.
Files changed (39) hide show
  1. data/.gitignore +1 -0
  2. data/Rakefile +1 -1
  3. data/VERSION +1 -1
  4. data/bin/ai +22 -1
  5. data/bin/ttai +47 -0
  6. data/csd.gemspec +15 -6
  7. data/lib/csd.rb +75 -16
  8. data/lib/csd/application/decklink/base.rb +2 -2
  9. data/lib/csd/application/default.rb +2 -3
  10. data/lib/csd/application/default/base.rb +5 -2
  11. data/lib/csd/application/i2conf.rb +28 -0
  12. data/lib/csd/application/i2conf/about.yml +8 -0
  13. data/lib/csd/application/i2conf/base.rb +215 -0
  14. data/lib/csd/application/i2conf/config_example.rb +22 -0
  15. data/lib/csd/application/i2conf/options/common.rb +11 -0
  16. data/lib/csd/application/i2conf/options/common_defaults.rb +4 -0
  17. data/lib/csd/application/i2conf/options/install.rb +10 -0
  18. data/lib/csd/application/i2conf/options/install_defaults.rb +4 -0
  19. data/lib/csd/application/minisip.rb +8 -12
  20. data/lib/csd/application/minisip/about.yml +12 -4
  21. data/lib/csd/application/minisip/base.rb +40 -1
  22. data/lib/csd/application/minisip/component.rb +2 -0
  23. data/lib/csd/application/minisip/component/core.rb +13 -6
  24. data/lib/csd/application/minisip/component/gnome.rb +1 -0
  25. data/lib/csd/application/minisip/component/network.rb +95 -0
  26. data/lib/csd/application/minisip/component/plugins.rb +1 -1
  27. data/lib/csd/application/minisip/options/{compile.rb → install.rb} +4 -0
  28. data/lib/csd/application/minisip/options/{compile_defaults.rb → install_defaults.rb} +2 -1
  29. data/lib/csd/application/minisip/phonebook_example.rb +41 -12
  30. data/lib/csd/application/minisip/unix.rb +24 -17
  31. data/lib/csd/application/minisip/unix/linux/debian.rb +13 -5
  32. data/lib/csd/application/minisip/unix/linux/debian/ubuntu10.rb +3 -2
  33. data/lib/csd/applications.rb +1 -1
  34. data/lib/csd/commands.rb +23 -5
  35. data/lib/csd/extensions/gem/platform.rb +12 -0
  36. data/lib/csd/options_parser.rb +31 -11
  37. data/test/application/test_minisip.rb +63 -6
  38. data/test/functional/test_options.rb +82 -3
  39. metadata +19 -8
@@ -9,12 +9,13 @@ module CSD
9
9
  # This method presents a general overview about the task that is to be performed.
10
10
  #
11
11
  def introduction
12
+ UI.debug "Components to be processed: #{components.inspect}"
12
13
  if Options.developer
13
- Core.introduction
14
- # FFmpeg.introduction
15
- # HDVIPER.introduction
16
- # X264.introduction
17
- # Plugins.introduction
14
+ Core.introduction if component? 'core'
15
+ FFmpeg.introduction if component? 'ffmpeg'
16
+ HDVIPER.introduction if component? 'hdviper'
17
+ X264.introduction if component? 'x264'
18
+ Plugins.introduction if component? 'plugins'
18
19
  UI.separator
19
20
  end
20
21
  super
@@ -24,7 +25,11 @@ module CSD
24
25
  #
25
26
  def compile
26
27
  UI.separator
27
- UI.info "This operation will compile MiniSIP and its dependencies.".green.bold
28
+ if all_components?
29
+ UI.info "This operation will install MiniSIP and its dependencies.".green.bold
30
+ else
31
+ UI.info "This operation will install the #{Options.scope} component of MiniSIP.".green.bold
32
+ end
28
33
  UI.separator
29
34
  install_mode = Options.this_user ? 'Only for this user (inside the working directory)' : 'For all users (sudo)'
30
35
  UI.info " Installation mode: ".green.bold + install_mode.yellow
@@ -45,18 +50,19 @@ module CSD
45
50
  #
46
51
  def compile!
47
52
  create_working_directory
48
- HDVIPER.compile
53
+ HDVIPER.compile if component? 'hdviper'
49
54
  if Options.ffmpeg_first
50
- X264.compile
51
- FFmpeg.compile
52
- Core.compile
55
+ X264.compile if component? 'x264'
56
+ FFmpeg.compile if component? 'ffmpeg'
57
+ Core.compile if component? 'core'
53
58
  else
54
- Core.compile
55
- X264.compile
56
- FFmpeg.compile
59
+ Core.compile if component? 'core'
60
+ X264.compile if component? 'x264'
61
+ FFmpeg.compile if component? 'ffmpeg'
57
62
  end
58
- Plugins.compile
59
- Gnome.compile
63
+ Plugins.compile if component? 'plugins'
64
+ Network.compile if component? 'network'
65
+ Gnome.compile if component? 'gnome'
60
66
  congratulations
61
67
  end
62
68
 
@@ -65,9 +71,10 @@ module CSD
65
71
  Core.run_gtkgui
66
72
  else
67
73
  cleanup_working_directory
74
+ return unless all_components?
68
75
  UI.separator
69
- UI.info "MiniSIP installation complete.".green.bold
70
- UI.info "Please have a look in your Applications menu -> Internet."
76
+ UI.info " MiniSIP installation complete.".green.bold
77
+ UI.info " Please have a look in your applications menu -> Internet."
71
78
  UI.separator
72
79
  # Core.run_gtkgui # At this point we could run MiniSIP instead of ending the AI -- if we wanted to.
73
80
  end
@@ -8,10 +8,10 @@ module CSD
8
8
 
9
9
  # A list of apt-get packages that are required to compile minisip including hdviper and ffmpeg
10
10
  #
11
- DEBIAN_DEPENDENCIES = %w{ automake build-essential checkinstall git-core libnotify-bin libasound2-dev libavcodec-dev libglademm-2.4-dev libgtkmm-2.4-dev libltdl3-dev libsdl-dev libsdl-ttf2.0-dev libssl-dev libtool libswscale-dev libx11-dev libxv-dev nasm subversion yasm }
11
+ DEBIAN_DEPENDENCIES = %w{ automake build-essential checkinstall git-core libasound2-dev libavcodec-dev libglademm-2.4-dev libgtkmm-2.4-dev libltdl3-dev libnotify-bin libsdl-dev libsdl-ttf2.0-dev libssl-dev libswscale-dev libtool libx11-dev libxv-dev nasm subversion yasm }
12
12
 
13
13
  def compile!
14
- aptitude if Options.apt_get
14
+ aptitude
15
15
  after_aptitude
16
16
  super
17
17
  end
@@ -20,14 +20,22 @@ module CSD
20
20
  end
21
21
 
22
22
  def package!
23
+ create_working_directory
23
24
  Core.modify_libminisip_rules # TODO: Oursource into Component::Core
24
25
  super
25
26
  end
26
27
 
27
28
  def aptitude
28
- UI.info "Installing Debian dependencies".green.bold
29
- Cmd.run("sudo apt-get update")
30
- Cmd.run("sudo apt-get install #{DEBIAN_DEPENDENCIES.sort.join(' ')} --yes --fix-missing")
29
+ return unless Options.apt_get
30
+ UI.info "Installing Debian dependencies for MiniSIP".green.bold
31
+ Cmd.run 'sudo apt-get update', :announce_pwd => false
32
+ Cmd.run "sudo apt-get install #{DEBIAN_DEPENDENCIES.sort.join(' ')} --yes --fix-missing", :announce_pwd => false
33
+ # For some reason OpenGL crashes if we try to use this packet.
34
+ # return unless Gem::Platform.local.ubuntu_10? or Options.reveal
35
+ # UI.info "Installing 2D/3D acceleration for ATI graphic cards".green.bold
36
+ # Note that aptitude will not fail if the package cannot be found. This is very useful, because fglrx does not
37
+ # exist on Ubuntu 9.10, yet this command will not fail. Apt-get install would fail.
38
+ # Cmd.run "sudo aptitude install fglrx -y", :announce_pwd => false, :die_on_failure => false
31
39
  end
32
40
 
33
41
  end
@@ -7,6 +7,7 @@ module CSD
7
7
  class Ubuntu10 < Debian
8
8
 
9
9
  def after_aptitude
10
+ create_working_directory
10
11
  fix_ubuntu_10_04
11
12
  super
12
13
  end
@@ -24,8 +25,8 @@ module CSD
24
25
  end
25
26
  # We cannot use Cmd.copy here, because Cmd.copy has no superuser privileges.
26
27
  # And since we are for sure on Ubuntu, these commands will work.
27
- Cmd.run("sudo cp #{Path.giomm_header} #{Path.giomm_header_backup}")
28
- Cmd.run("sudo cp #{Path.new_giomm_header} #{Path.giomm_header}")
28
+ Cmd.run "sudo cp #{Path.giomm_header} #{Path.giomm_header_backup}", :announce_pwd => false
29
+ Cmd.run "sudo cp #{Path.new_giomm_header} #{Path.giomm_header}", :announce_pwd => false
29
30
  end
30
31
  end
31
32
 
@@ -27,7 +27,7 @@ module CSD
27
27
  #
28
28
  def self.all(&block)
29
29
  result = []
30
- Dir.directories(Path.applications) do |dir|
30
+ Dir.directories(Path.applications).sort.each do |dir|
31
31
  next if dir == 'default'
32
32
  if app = find(dir)
33
33
  block_given? ? yield(app) : result << app
@@ -173,14 +173,19 @@ module CSD
173
173
  #
174
174
  def self.replace(pattern, substitution, params={})
175
175
  result = CommandResult.new
176
- default_params = { :die_on_failure => true }
176
+ default_params = { :die_on_failure => true, :only_first_occurence => false }
177
177
  params = default_params.merge(params)
178
178
  begin
179
- UI.info " Replacing".yellow
179
+ new_file_content = if params[:only_first_occurence]
180
+ UI.info " Replacing the first occurence of".yellow
181
+ File.read(self.filepath).sub(pattern.to_s, substitution.to_s)
182
+ else
183
+ UI.info " Replacing".yellow
184
+ File.read(self.filepath).gsub(pattern.to_s, substitution.to_s)
185
+ end
180
186
  UI.info " `#{pattern}´".blue
181
187
  UI.info " with".yellow
182
188
  UI.info " `#{substitution.to_s.gsub("\n", "\n ")}´".white
183
- new_file_content = File.read(self.filepath).gsub(pattern.to_s, substitution.to_s)
184
189
  File.open(self.filepath, 'w+') { |file| file << new_file_content } unless Options.reveal
185
190
  result.success = true
186
191
  rescue Errno::ENOENT => e
@@ -212,7 +217,7 @@ module CSD
212
217
  #
213
218
  # This method returns a CommandResult object with the following values:
214
219
  #
215
- # [+output?+] The command's output as a +String+ (with newline delimiters). Note that the status code can be accessed via the global variable <tt>$?</tt>.
220
+ # [+output+] The command's output as a +String+ (with newline delimiters). Note that the status code can be accessed via the global variable <tt>$?</tt>.
216
221
  # [+status?+] Contains <tt>$?</tt> and all the methods Ruby provides for it.
217
222
  # [+success?+] +true+ if the command was successful, +nil+ if not (internally <tt>$?.success?</tt> is called).
218
223
  #
@@ -314,7 +319,20 @@ module CSD
314
319
  Cmd.run("git clone #{repository} #{destination}", :announce_pwd => false)
315
320
  end
316
321
  end
317
-
322
+
323
+ # This downloads a file. It could be replaced by Ruby internals in the future to make it work in Windows.
324
+ # The CommandResult of <tt>Cmd.run</tt> is returned, so <tt>result.success?</tt> will indicate whether
325
+ # the download was successful or not.
326
+ #
327
+ def download(url, destination)
328
+ if Cmd.run('curl -h', :internal => true, :die_on_failure => false).success?
329
+ # Darwin
330
+ Cmd.run "curl #{url} --location -o #{destination}", :die_on_failure => false, :announce_pwd => false
331
+ elsif Cmd.run('wget -h', :internal => true, :die_on_failure => false).success?
332
+ # Linux
333
+ Cmd.run "wget #{url} -O #{destination}", :die_on_failure => false, :announce_pwd => false
334
+ end
335
+ end
318
336
  end
319
337
 
320
338
  # Objects of this class can be returned by Commands. Since it is an OpenStruct object,
@@ -22,6 +22,18 @@ module CSD
22
22
  kernel_version and kernel_version =~ /Debian|Ubuntu/
23
23
  end
24
24
 
25
+ # Determines whether the OS is Ubuntu. Returns +true+ or +false+.
26
+ #
27
+ def ubuntu?
28
+ kernel_version and kernel_version =~ /Ubuntu/
29
+ end
30
+
31
+ # Determines whether the OS is Ubuntu 10. Returns +true+ or +false+.
32
+ #
33
+ def ubuntu_10?
34
+ ubuntu? and %w{ 2.6.32-21-generic 2.6.32-22-generic }.include?(kernel_release)
35
+ end
36
+
25
37
  # On linux systems, this method returns the current kernel version.
26
38
  #
27
39
  def kernel_version
@@ -17,20 +17,27 @@ module CSD
17
17
  end
18
18
 
19
19
  def valid_action?
20
- public_actions = actions['public'] ? self.actions['public'].map { |pair| pair.keys.first } : []
21
- developer_actions = actions['developer'] ? self.actions['developer'].map { |pair| pair.keys.first } : []
22
- all_actions = public_actions + developer_actions
23
- all_actions.include?(self.action)
20
+ self.actions_names.include?(self.action)
21
+ end
22
+
23
+ def valid_scope?
24
+ self.scopes_names.include?(self.scope)
24
25
  end
25
26
 
26
27
  def define_actions_and_scopes
27
28
  if Applications.current
28
29
  # Here we overwrite the default supported actions and scopes with the application specific ones
29
- UI.debug "#{self.class} loads the actions of #{Applications.current} now"
30
- self.actions = Applications.current.actions
30
+ UI.debug "#{self.class}#define_actions_and_scopes loads the actions of #{Applications.current} now"
31
+ self.actions = Applications.current.actions
32
+ public_actions = actions['public'] ? self.actions['public'].map { |pair| pair.keys.first } : []
33
+ developer_actions = actions['developer'] ? self.actions['developer'].map { |pair| pair.keys.first } : []
34
+ self.actions_names = public_actions + developer_actions
35
+ UI.debug "#{self.class}#define_actions_and_scopes identified the actions #{self.actions_names.inspect}"
31
36
  # At this point we know that the first argument is no option, but *some* action (may it be valid or not)
32
- UI.debug "#{self.class} loads the scopes of #{Applications.current} now"
33
- self.scopes = Applications.current.scopes(self.action)
37
+ UI.debug "#{self.class}#define_actions_and_scopes loads the scopes of #{Applications.current} now"
38
+ self.scopes = Applications.current.scopes(self.action)
39
+ self.scopes_names = self.scopes.map { |pair| pair.keys.first }
40
+ UI.debug "#{self.class}#define_actions_and_scopes identified the scopes #{self.scopes_names.inspect}"
34
41
  end
35
42
  end
36
43
 
@@ -38,8 +45,10 @@ module CSD
38
45
  # Resetting all attributes to nil (because e.g. an application instance might have modified or added some).
39
46
  super()
40
47
  # First we define all valid actions and scopes
41
- self.actions = []
42
- self.scopes = []
48
+ self.actions = []
49
+ self.actions_names = []
50
+ self.scopes = []
51
+ self.scopes_names = []
43
52
  # Then we define the default literals
44
53
  self.help = false
45
54
  self.application = nil
@@ -79,7 +88,13 @@ module CSD
79
88
  self.action = ARGV.shift
80
89
  self.application = ARGV.shift # Removing the application name from the argument list
81
90
  end
91
+ # The only thing that is left is the scope, by now shifted from the third to the first location.
92
+ # A literal must now be the desired scope
93
+ if ARGV.first and not ARGV.first.starts_with?('-')
94
+ self.scope = ARGV.shift
95
+ end
82
96
  end
97
+ UI.debug "#{self.class}#parse_literals identified the application `#{self.application}´, the action `#{self.action}´ and the scope `#{self.scope}´"
83
98
  end
84
99
 
85
100
  # Parse all options that the user gave as command parameter. Note that this function strips the options
@@ -87,8 +102,13 @@ module CSD
87
102
  #
88
103
  def parse_options
89
104
  OptionParser.new do |opts|
90
- self.banner = Applications.current ? 'OPTIONS' : "Usage: ".bold + "#{CSD.executable} [help] [TASK] APPLICATION [OPTIONS]"
105
+ self.banner = "Usage: ".bold + "#{CSD.executable} [help] #{Options.action} #{Applications.current.name if Applications.current} [COMPONENT] [OPTIONS]".cyan
91
106
  opts.banner = self.banner.magenta.bold
107
+
108
+ unless Options.scopes_names.empty?
109
+ opts.headline "COMPONENTS".green.bold
110
+ scopes.flatten.each { |scope| opts.list_item(scope.keys.first, scope.values.first) }
111
+ end
92
112
 
93
113
  # Here we load application-specific options file.
94
114
  # TODO: There must be a better way for this in general than to eval the raw ruby code
@@ -12,6 +12,38 @@ class TestMinisip < Test::Unit::TestCase
12
12
  Options.clear
13
13
  Options.testmode = true
14
14
  end
15
+
16
+ context "Debian instance" do
17
+
18
+ setup do
19
+ @debian = ::CSD::Application::Minisip::Debian.new
20
+ end
21
+
22
+ context "*in theory* when compiling" do
23
+
24
+ setup do
25
+ Options.clear
26
+ @debian.define_relative_paths
27
+ Options.clear Application::Minisip.default_options('install')
28
+ Options.reveal = true
29
+ Options.testmode = true
30
+ end
31
+
32
+ should "by default run apt-get commands" do
33
+ assert Options.apt_get
34
+ out, err = capture { @debian.compile! }
35
+ assert_match /apt\-get update/, out
36
+ assert_match /apt\-get install/, out
37
+ end
38
+
39
+ should "skip apt-get if demanded" do
40
+ Options.apt_get = false
41
+ out, err = capture { @debian.compile! }
42
+ assert_no_match /apt\-get/, out
43
+ end
44
+
45
+ end
46
+ end
15
47
 
16
48
  context "Core component" do
17
49
 
@@ -37,7 +69,7 @@ class TestMinisip < Test::Unit::TestCase
37
69
  setup do
38
70
  Options.clear
39
71
  @base.define_relative_paths
40
- Options.clear Application::Minisip.default_options('compile')
72
+ Options.clear Application::Minisip.default_options('install')
41
73
  Options.reveal = true
42
74
  Options.testmode = true
43
75
  end
@@ -48,7 +80,7 @@ class TestMinisip < Test::Unit::TestCase
48
80
  assert Options.make
49
81
  assert Options.make_install
50
82
  end
51
-
83
+
52
84
  should "know how to checkout the default branch of the source code" do
53
85
  out, err = capture { Core.checkout }
54
86
  assert_match /git clone /, out
@@ -56,7 +88,7 @@ class TestMinisip < Test::Unit::TestCase
56
88
  assert_no_match /git checkout/, out
57
89
  assert err.empty?
58
90
  end
59
-
91
+
60
92
  should "know how to checkout a particular branch of the source code" do
61
93
  Options.branch = 'cuttingedge'
62
94
  out, err = capture { Core.checkout }
@@ -64,7 +96,7 @@ class TestMinisip < Test::Unit::TestCase
64
96
  assert_match /git checkout .+ cuttingedge/, out
65
97
  assert err.empty?
66
98
  end
67
-
99
+
68
100
  should "use sudo make install instead of make install by default" do
69
101
  out, err = capture { Core.compile }
70
102
  # TODO: This should be a more strict test
@@ -80,8 +112,8 @@ class TestMinisip < Test::Unit::TestCase
80
112
  should "remove ffmpeg before compiling minisip" do
81
113
  Options.debug = true
82
114
  out, err = capture { Core.compile }
83
- assert_match /MILESTONE: removing_ffmpeg.+MILESTONE: processing_libminisip/m, out
84
- assert_no_match /MILESTONE: processing_libminisip.+MILESTONE: removing_ffmpeg/m, out
115
+ assert_match /MILESTONE_removing_ffmpeg.+MILESTONE_processing_libminisip/m, out
116
+ assert_no_match /MILESTONE_processing_libminisip.+MILESTONE_removing_ffmpeg/m, out
85
117
  end
86
118
 
87
119
  should "not link the library in this-user-mode" do
@@ -91,7 +123,32 @@ class TestMinisip < Test::Unit::TestCase
91
123
  out, err = capture { Core.compile }
92
124
  assert_no_match /ldconfig/, out
93
125
  end
126
+
127
+ should "process libraries without parameters when demanded" do
128
+ Options.debug = true
129
+ Options.blank_minisip_configuration = true
130
+ out, err = capture { Core.compile_libraries }
131
+ assert_match /MILESTONE_processing_libmstun/, out
132
+ assert_match /MILESTONE_processing_libminisip/, out
133
+ assert_match /MILESTONE_processing_minisip/, out
134
+ assert_no_match /FLAGS/, out
135
+ assert_no_match /enable/, out
136
+ end
94
137
 
138
+ should "have no --enable-debug flag by default" do
139
+ Options.debug = true
140
+ out, err = capture { Core.compile_libraries }
141
+ assert_no_match /enable\-debug/, out
142
+ end
143
+
144
+ should "use --enable-debug flag if demanded" do
145
+ Options.debug = true
146
+ Options.enable_debug = true
147
+ out, err = capture { Core.compile_libraries }
148
+ assert_match /MILESTONE_processing_libminisip.+\-\-enable\-debug.+MILESTONE_processing_minisip.+\-\-enable\-debug/m, out
149
+ assert_no_match /\-\-enable\-debug.+MILESTONE_processing_libminisip/m, out
150
+ end
151
+
95
152
  end # context "in theory when compiling"
96
153
 
97
154
  context "in practice" do
@@ -23,6 +23,7 @@ class TestOptions < Test::Unit::TestCase
23
23
  assert !Options.help
24
24
  assert !Options.application
25
25
  assert !Options.action
26
+ assert !Options.scope
26
27
  end
27
28
 
28
29
  should "find a lonely help parameter" do
@@ -31,6 +32,7 @@ class TestOptions < Test::Unit::TestCase
31
32
  assert Options.help
32
33
  assert !Options.application
33
34
  assert !Options.action
35
+ assert !Options.scope
34
36
  end
35
37
 
36
38
  context "together with a valid application" do
@@ -46,6 +48,7 @@ class TestOptions < Test::Unit::TestCase
46
48
  assert !Options.help
47
49
  assert_equal @app, Options.application
48
50
  assert !Options.action
51
+ assert !Options.scope
49
52
  end
50
53
 
51
54
  should "find an action along with the application" do
@@ -55,6 +58,18 @@ class TestOptions < Test::Unit::TestCase
55
58
  assert !Options.help
56
59
  assert_equal 'myaction', Options.action
57
60
  assert_equal @app, Options.application
61
+ assert !Options.scope
62
+ end
63
+
64
+ should "find an action along with the application and a scope" do
65
+ ARGV.push 'myaction'
66
+ ARGV.push @app
67
+ ARGV.push 'myscope'
68
+ Options.parse_literals
69
+ assert !Options.help
70
+ assert_equal 'myaction', Options.action
71
+ assert_equal @app, Options.application
72
+ assert_equal 'myscope', Options.scope
58
73
  end
59
74
 
60
75
  should "find an action along with the application in help mode" do
@@ -65,6 +80,19 @@ class TestOptions < Test::Unit::TestCase
65
80
  assert Options.help
66
81
  assert_equal 'myaction', Options.action
67
82
  assert_equal @app, Options.application
83
+ assert !Options.scope
84
+ end
85
+
86
+ should "find an action along with the application and a scope in help mode" do
87
+ ARGV.push 'help'
88
+ ARGV.push 'myaction'
89
+ ARGV.push @app
90
+ ARGV.push 'myscope'
91
+ Options.parse_literals
92
+ assert Options.help
93
+ assert_equal 'myaction', Options.action
94
+ assert_equal @app, Options.application
95
+ assert_equal 'myscope', Options.scope
68
96
  end
69
97
 
70
98
  should "understand whether an action is invalid" do
@@ -72,11 +100,62 @@ class TestOptions < Test::Unit::TestCase
72
100
  ARGV.push 'invalid_action'
73
101
  ARGV.push @app
74
102
  Options.parse_literals
75
- Options.actions = {'valid_action' => 'I am valid'}
76
- assert_includes 'valid_action', Options.actions
103
+ Options.actions_names = ['valid_action']
77
104
  assert !Options.valid_action?
105
+ assert !Options.valid_scope?
106
+ assert !Options.scope
78
107
  end
79
-
108
+
109
+ should "understand whether an action is invalid when a scope is given" do
110
+ ARGV.push 'help'
111
+ ARGV.push 'invalid_action'
112
+ ARGV.push @app
113
+ ARGV.push 'myscope'
114
+ Options.parse_literals
115
+ Options.actions_names = ['valid_action']
116
+ assert !Options.valid_action?
117
+ assert !Options.valid_scope?
118
+ assert_equal 'myscope', Options.scope
119
+ end
120
+
121
+ should "understand whether an action is valid when a scope is given" do
122
+ ARGV.push 'help'
123
+ ARGV.push 'valid_action'
124
+ ARGV.push @app
125
+ ARGV.push 'myscope'
126
+ Options.parse_literals
127
+ Options.actions_names = ['valid_action']
128
+ assert Options.valid_action?
129
+ assert !Options.valid_scope?
130
+ assert_equal 'myscope', Options.scope
131
+ end
132
+
133
+ should "understand whether a scope is invalid when a valid action is given" do
134
+ ARGV.push 'help'
135
+ ARGV.push 'valid_action'
136
+ ARGV.push @app
137
+ ARGV.push 'invalid_scope'
138
+ Options.parse_literals
139
+ Options.actions_names = ['valid_action']
140
+ Options.scopes_names = ['valid_scope']
141
+ assert Options.valid_action?
142
+ assert !Options.valid_scope?
143
+ assert_equal 'invalid_scope', Options.scope
144
+ end
145
+
146
+ should "understand whether a scope is valid when a valid action is given" do
147
+ ARGV.push 'help'
148
+ ARGV.push 'valid_action'
149
+ ARGV.push @app
150
+ ARGV.push 'valid_scope'
151
+ Options.parse_literals
152
+ Options.actions_names = ['valid_action']
153
+ Options.scopes_names = ['valid_scope']
154
+ assert Options.valid_action?
155
+ assert Options.valid_scope?
156
+ assert_equal 'valid_scope', Options.scope
157
+ end
158
+
80
159
  end # context "together with a valid application"
81
160
 
82
161
  end # context "and identifying help/action/application, parse_literals"