csd 0.1.18 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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"