adhearsion 1.2.6 → 2.0.0.alpha1
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/.gitignore +17 -10
- data/CHANGELOG.md +273 -0
- data/Gemfile +1 -1
- data/Guardfile +17 -0
- data/README.markdown +61 -9
- data/Rakefile +16 -48
- data/adhearsion.gemspec +21 -7
- data/bin/ahn +3 -1
- data/cucumber.yml +4 -0
- data/features/app_generator.feature +42 -0
- data/features/cli.feature +108 -0
- data/features/step_definitions/app_generator_steps.rb +6 -0
- data/features/step_definitions/cli_steps.rb +74 -0
- data/features/support/aruba_helper.rb +22 -0
- data/features/support/env.rb +37 -0
- data/features/support/utils.rb +8 -0
- data/lib/adhearsion.rb +85 -41
- data/lib/adhearsion/call.rb +176 -0
- data/lib/adhearsion/call_controller.rb +134 -0
- data/lib/adhearsion/call_controller/dial.rb +70 -0
- data/lib/adhearsion/call_controller/input.rb +173 -0
- data/lib/adhearsion/call_controller/menu.rb +124 -0
- data/lib/adhearsion/call_controller/output.rb +267 -0
- data/lib/adhearsion/call_controller/record.rb +42 -0
- data/lib/adhearsion/call_controller/utility.rb +60 -0
- data/lib/adhearsion/calls.rb +81 -0
- data/lib/adhearsion/cli.rb +1 -3
- data/lib/adhearsion/cli_commands.rb +142 -0
- data/lib/adhearsion/configuration.rb +149 -0
- data/lib/adhearsion/console.rb +19 -8
- data/lib/adhearsion/dialplan_controller.rb +9 -0
- data/lib/adhearsion/events.rb +84 -0
- data/lib/adhearsion/foundation/all.rb +0 -7
- data/lib/adhearsion/foundation/custom_daemonizer.rb +4 -6
- data/lib/adhearsion/foundation/exception_handler.rb +9 -0
- data/lib/adhearsion/foundation/object.rb +26 -8
- data/lib/adhearsion/foundation/synchronized_hash.rb +3 -6
- data/lib/adhearsion/foundation/thread_safety.rb +17 -1
- data/lib/adhearsion/generators/app/app_generator.rb +4 -13
- data/lib/adhearsion/generators/app/templates/Gemfile +10 -5
- data/lib/adhearsion/generators/app/templates/Procfile +1 -0
- data/lib/adhearsion/generators/app/templates/README.md +28 -0
- data/lib/adhearsion/generators/app/templates/config/adhearsion.rb +41 -0
- data/lib/adhearsion/generators/app/templates/{components/simon_game → lib}/simon_game.rb +6 -18
- data/lib/adhearsion/generators/app/templates/script/ahn +2 -2
- data/lib/adhearsion/initializer.rb +151 -293
- data/lib/adhearsion/initializer/logging.rb +33 -0
- data/lib/adhearsion/logging.rb +65 -69
- data/lib/adhearsion/menu_dsl.rb +15 -0
- data/lib/adhearsion/menu_dsl/calculated_match.rb +39 -0
- data/lib/adhearsion/menu_dsl/calculated_match_collection.rb +41 -0
- data/lib/adhearsion/menu_dsl/fixnum_match_calculator.rb +18 -0
- data/lib/adhearsion/menu_dsl/match_calculator.rb +36 -0
- data/lib/adhearsion/{voip/menu_state_machine/menu_class.rb → menu_dsl/menu.rb} +38 -40
- data/lib/adhearsion/menu_dsl/menu_builder.rb +69 -0
- data/lib/adhearsion/menu_dsl/range_match_calculator.rb +55 -0
- data/lib/adhearsion/menu_dsl/string_match_calculator.rb +21 -0
- data/lib/adhearsion/outbound_call.rb +64 -0
- data/lib/adhearsion/plugin.rb +319 -0
- data/lib/adhearsion/plugin/collection.rb +19 -0
- data/lib/adhearsion/plugin/initializer.rb +37 -0
- data/lib/adhearsion/plugin/methods_container.rb +6 -0
- data/lib/adhearsion/process.rb +94 -0
- data/lib/adhearsion/punchblock_plugin.rb +29 -0
- data/lib/adhearsion/punchblock_plugin/initializer.rb +137 -0
- data/lib/adhearsion/router.rb +30 -0
- data/lib/adhearsion/router/route.rb +42 -0
- data/lib/adhearsion/script_ahn_loader.rb +2 -2
- data/lib/adhearsion/tasks.rb +14 -9
- data/lib/adhearsion/tasks/configuration.rb +26 -0
- data/lib/adhearsion/tasks/plugins.rb +17 -0
- data/lib/adhearsion/version.rb +8 -14
- data/spec/adhearsion/call_controller/dial_spec.rb +138 -0
- data/spec/adhearsion/call_controller/input_spec.rb +278 -0
- data/spec/adhearsion/call_controller/menu_spec.rb +120 -0
- data/spec/adhearsion/call_controller/output_spec.rb +466 -0
- data/spec/adhearsion/call_controller/record_spec.rb +125 -0
- data/spec/adhearsion/call_controller_spec.rb +395 -0
- data/spec/adhearsion/call_spec.rb +438 -0
- data/spec/adhearsion/calls_spec.rb +47 -0
- data/spec/adhearsion/configuration_spec.rb +308 -0
- data/spec/adhearsion/dialplan_controller_spec.rb +26 -0
- data/spec/adhearsion/events_spec.rb +112 -0
- data/spec/adhearsion/initializer/logging_spec.rb +58 -0
- data/spec/adhearsion/initializer_spec.rb +209 -122
- data/spec/adhearsion/logging_spec.rb +58 -47
- data/spec/adhearsion/menu_dsl/calculated_match_collection_spec.rb +56 -0
- data/spec/adhearsion/menu_dsl/calculated_match_spec.rb +57 -0
- data/spec/adhearsion/menu_dsl/fixnum_match_calculator_spec.rb +33 -0
- data/spec/adhearsion/menu_dsl/match_calculator_spec.rb +13 -0
- data/spec/adhearsion/menu_dsl/menu_builder_spec.rb +118 -0
- data/spec/adhearsion/menu_dsl/menu_spec.rb +210 -0
- data/spec/adhearsion/menu_dsl/range_match_calculator_spec.rb +28 -0
- data/spec/adhearsion/menu_dsl/string_match_calculator_spec.rb +36 -0
- data/spec/adhearsion/menu_dsl_spec.rb +12 -0
- data/spec/adhearsion/outbound_call_spec.rb +174 -0
- data/spec/adhearsion/plugin_spec.rb +489 -0
- data/spec/adhearsion/process_spec.rb +34 -0
- data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +294 -0
- data/spec/adhearsion/router/route_spec.rb +99 -0
- data/spec/adhearsion/router_spec.rb +106 -0
- data/spec/adhearsion_spec.rb +46 -0
- data/spec/spec_helper.rb +14 -14
- data/spec/support/call_controller_test_helpers.rb +48 -0
- data/spec/support/initializer_stubs.rb +8 -13
- data/spec/support/punchblock_mocks.rb +6 -0
- metadata +255 -253
- data/CHANGELOG +0 -174
- data/bin/ahnctl +0 -68
- data/bin/jahn +0 -43
- data/examples/asterisk_manager_interface/standalone.rb +0 -51
- data/lib/adhearsion/commands.rb +0 -302
- data/lib/adhearsion/component_manager.rb +0 -278
- data/lib/adhearsion/component_manager/component_tester.rb +0 -54
- data/lib/adhearsion/component_manager/spec_framework.rb +0 -18
- data/lib/adhearsion/events_support.rb +0 -65
- data/lib/adhearsion/foundation/blank_slate.rb +0 -3
- data/lib/adhearsion/foundation/event_socket.rb +0 -205
- data/lib/adhearsion/foundation/future_resource.rb +0 -36
- data/lib/adhearsion/foundation/metaprogramming.rb +0 -17
- data/lib/adhearsion/foundation/numeric.rb +0 -13
- data/lib/adhearsion/foundation/pseudo_guid.rb +0 -10
- data/lib/adhearsion/foundation/relationship_properties.rb +0 -42
- data/lib/adhearsion/foundation/string.rb +0 -26
- data/lib/adhearsion/generators/app/templates/.ahnrc +0 -34
- data/lib/adhearsion/generators/app/templates/README +0 -8
- data/lib/adhearsion/generators/app/templates/components/ami_remote/ami_remote.rb +0 -15
- data/lib/adhearsion/generators/app/templates/components/disabled/HOW_TO_ENABLE +0 -7
- data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/README.markdown +0 -47
- data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.rb +0 -34
- data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.yml +0 -12
- data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/README.markdown +0 -3
- data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.rb +0 -11
- data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.yml +0 -0
- data/lib/adhearsion/generators/app/templates/config/startup.rb +0 -81
- data/lib/adhearsion/generators/app/templates/dialplan.rb +0 -3
- data/lib/adhearsion/generators/app/templates/events.rb +0 -33
- data/lib/adhearsion/host_definitions.rb +0 -67
- data/lib/adhearsion/initializer/asterisk.rb +0 -86
- data/lib/adhearsion/initializer/configuration.rb +0 -324
- data/lib/adhearsion/initializer/database.rb +0 -60
- data/lib/adhearsion/initializer/drb.rb +0 -31
- data/lib/adhearsion/initializer/freeswitch.rb +0 -22
- data/lib/adhearsion/initializer/ldap.rb +0 -57
- data/lib/adhearsion/initializer/rails.rb +0 -41
- data/lib/adhearsion/initializer/xmpp.rb +0 -42
- data/lib/adhearsion/tasks/components.rb +0 -32
- data/lib/adhearsion/tasks/database.rb +0 -5
- data/lib/adhearsion/tasks/deprecations.rb +0 -59
- data/lib/adhearsion/tasks/generating.rb +0 -20
- data/lib/adhearsion/tasks/lint.rb +0 -4
- data/lib/adhearsion/voip/asterisk.rb +0 -4
- data/lib/adhearsion/voip/asterisk/agi_server.rb +0 -121
- data/lib/adhearsion/voip/asterisk/commands.rb +0 -1966
- data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +0 -140
- data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +0 -102
- data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +0 -250
- data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +0 -240
- data/lib/adhearsion/voip/asterisk/config_manager.rb +0 -64
- data/lib/adhearsion/voip/asterisk/manager_interface.rb +0 -697
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +0 -1681
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +0 -341
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +0 -78
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +0 -87
- data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +0 -80
- data/lib/adhearsion/voip/call.rb +0 -521
- data/lib/adhearsion/voip/call_routing.rb +0 -64
- data/lib/adhearsion/voip/commands.rb +0 -17
- data/lib/adhearsion/voip/constants.rb +0 -39
- data/lib/adhearsion/voip/conveniences.rb +0 -18
- data/lib/adhearsion/voip/dial_plan.rb +0 -252
- data/lib/adhearsion/voip/dsl/dialing_dsl.rb +0 -151
- data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +0 -37
- data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +0 -27
- data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +0 -124
- data/lib/adhearsion/voip/dsl/dialplan/parser.rb +0 -69
- data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +0 -16
- data/lib/adhearsion/voip/dsl/numerical_string.rb +0 -128
- data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +0 -48
- data/lib/adhearsion/voip/freeswitch/event_handler.rb +0 -58
- data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +0 -129
- data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +0 -38
- data/lib/adhearsion/voip/freeswitch/oes_server.rb +0 -195
- data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +0 -80
- data/lib/adhearsion/voip/menu_state_machine/matchers.rb +0 -123
- data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +0 -57
- data/lib/adhearsion/xmpp/connection.rb +0 -61
- data/lib/theatre.rb +0 -147
- data/lib/theatre/README.markdown +0 -64
- data/lib/theatre/callback_definition_loader.rb +0 -86
- data/lib/theatre/guid.rb +0 -23
- data/lib/theatre/invocation.rb +0 -131
- data/lib/theatre/namespace_manager.rb +0 -153
- data/lib/theatre/version.rb +0 -2
- data/spec/adhearsion/cli_spec.rb +0 -306
- data/spec/adhearsion/component_manager_spec.rb +0 -292
- data/spec/adhearsion/constants_spec.rb +0 -8
- data/spec/adhearsion/drb_spec.rb +0 -65
- data/spec/adhearsion/fixtures/dialplan.rb +0 -3
- data/spec/adhearsion/foundation/event_socket_spec.rb +0 -168
- data/spec/adhearsion/host_definitions_spec.rb +0 -79
- data/spec/adhearsion/initializer/configuration_spec.rb +0 -291
- data/spec/adhearsion/initializer/loading_spec.rb +0 -154
- data/spec/adhearsion/initializer/paths_spec.rb +0 -74
- data/spec/adhearsion/relationship_properties_spec.rb +0 -54
- data/spec/adhearsion/voip/asterisk/agi_server_spec.rb +0 -473
- data/spec/adhearsion/voip/asterisk/ami/ami_spec.rb +0 -550
- data/spec/adhearsion/voip/asterisk/ami/lexer/ami_fixtures.yml +0 -30
- data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story +0 -291
- data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story.rb +0 -241
- data/spec/adhearsion/voip/asterisk/ami/lexer/story_helper.rb +0 -124
- data/spec/adhearsion/voip/asterisk/commands_spec.rb +0 -3241
- data/spec/adhearsion/voip/asterisk/config_file_generators/agents_spec.rb +0 -251
- data/spec/adhearsion/voip/asterisk/config_file_generators/queues_spec.rb +0 -323
- data/spec/adhearsion/voip/asterisk/config_file_generators/voicemail_spec.rb +0 -306
- data/spec/adhearsion/voip/asterisk/config_manager_spec.rb +0 -127
- data/spec/adhearsion/voip/asterisk/menu_command/calculated_match_spec.rb +0 -109
- data/spec/adhearsion/voip/asterisk/menu_command/matchers_spec.rb +0 -97
- data/spec/adhearsion/voip/call_routing_spec.rb +0 -125
- data/spec/adhearsion/voip/dialplan_manager_spec.rb +0 -468
- data/spec/adhearsion/voip/dsl/dialing_dsl_spec.rb +0 -270
- data/spec/adhearsion/voip/dsl/dispatcher_spec.rb +0 -82
- data/spec/adhearsion/voip/dsl/dispatcher_spec_helper.rb +0 -45
- data/spec/adhearsion/voip/dsl/parser_spec.rb +0 -69
- data/spec/adhearsion/voip/freeswitch/basic_connection_manager_spec.rb +0 -39
- data/spec/adhearsion/voip/freeswitch/inbound_connection_manager_spec.rb +0 -39
- data/spec/adhearsion/voip/freeswitch/oes_server_spec.rb +0 -9
- data/spec/adhearsion/voip/numerical_string_spec.rb +0 -61
- data/spec/adhearsion/voip/phone_number_spec.rb +0 -45
- data/spec/support/the_following_code.rb +0 -3
- data/spec/theatre/dsl_examples/simple_before_call.rb +0 -7
- data/spec/theatre/dsl_spec.rb +0 -69
- data/spec/theatre/invocation_spec.rb +0 -182
- data/spec/theatre/namespace_spec.rb +0 -125
- data/spec/theatre/spec_helper_spec.rb +0 -28
- data/spec/theatre/theatre_class_spec.rb +0 -148
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
module Theatre
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
# This class provides the a wrapper aroung which an events.rb file can be instance_eval'd.
|
|
5
|
-
#
|
|
6
|
-
class CallbackDefinitionLoader
|
|
7
|
-
|
|
8
|
-
attr_reader :theatre, :root_name
|
|
9
|
-
def initialize(theatre, root_name=:events)
|
|
10
|
-
@theatre = theatre
|
|
11
|
-
@root_name = root_name
|
|
12
|
-
|
|
13
|
-
create_recorder_method root_name
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def anonymous_recorder
|
|
17
|
-
BlankSlateMessageRecorder.new(&method(:callback_registered))
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
##
|
|
21
|
-
# Parses the given Ruby source code file and returns this object.
|
|
22
|
-
#
|
|
23
|
-
# @param [String, File] file The filename or File object for the Ruby source code file to parse.
|
|
24
|
-
#
|
|
25
|
-
def load_events_file(file)
|
|
26
|
-
file = File.open(file) if file.kind_of? String
|
|
27
|
-
instance_eval file.read, file.path
|
|
28
|
-
self
|
|
29
|
-
ensure
|
|
30
|
-
file.close
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
##
|
|
34
|
-
# Parses the given Ruby source code and returns this object.
|
|
35
|
-
#
|
|
36
|
-
# NOTE: Only use this if you're generating the code yourself! If you're loading a file from the filesystem, you should
|
|
37
|
-
# use load_events_file() since load_events_file() will properly attribute errors in the code to the file from which the
|
|
38
|
-
# code was loaded.
|
|
39
|
-
#
|
|
40
|
-
# @param [String] code The Ruby source code to parse
|
|
41
|
-
#
|
|
42
|
-
def load_events_code(code)
|
|
43
|
-
instance_eval code
|
|
44
|
-
self
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
protected
|
|
48
|
-
|
|
49
|
-
##
|
|
50
|
-
# Immediately register the namespace and callback with the Theatre instance given to the constructor. This method is only
|
|
51
|
-
# called when a new BlankSlateMessageRecorder is instantiated and receives #each().
|
|
52
|
-
#
|
|
53
|
-
def callback_registered(namespaces, callback)
|
|
54
|
-
# Get rid of all arguments passed to the namespaces. Will support arguments in the future.
|
|
55
|
-
namespaces = namespaces.map { |namespace| namespace.first }
|
|
56
|
-
|
|
57
|
-
theatre.namespace_manager.register_callback_at_namespace namespaces, callback
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def create_recorder_method(record_method_name)
|
|
61
|
-
(class << self; self; end).send(:alias_method, record_method_name, :anonymous_recorder)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
class BlankSlateMessageRecorder
|
|
65
|
-
|
|
66
|
-
(instance_methods.map{|m| m.to_sym} - [:instance_eval, :object_id]).each { |method| undef_method method unless method.to_s =~ /^__/ }
|
|
67
|
-
|
|
68
|
-
def initialize(¬ify_on_completion)
|
|
69
|
-
@notify_on_completion = notify_on_completion
|
|
70
|
-
@namespaces = []
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def method_missing(*method_name_and_args)
|
|
74
|
-
raise ArgumentError, "Supplying a block is not supported" if block_given?
|
|
75
|
-
@namespaces << method_name_and_args
|
|
76
|
-
self
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def each(&callback)
|
|
80
|
-
@notify_on_completion.call(@namespaces, callback)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
end
|
|
86
|
-
end
|
data/lib/theatre/guid.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# Right now Adhearsion also defines this method. The eventual solution will be to extract the Adhearsion features on which
|
|
2
|
-
# Theatre depends and make that a dependent library.
|
|
3
|
-
|
|
4
|
-
unless respond_to? :new_guid
|
|
5
|
-
|
|
6
|
-
def random_character
|
|
7
|
-
case random_digit = rand(62)
|
|
8
|
-
when 0...10 then random_digit.to_s
|
|
9
|
-
when 10...36 then (random_digit + 55).chr
|
|
10
|
-
when 36...62 then (random_digit + 61).chr
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def random_string(length_of_string=8)
|
|
15
|
-
Array.new(length_of_string) { random_character }.join
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# This GUID implementation doesn't adhere to the RFC which wants to make certain segments based on the MAC address of a
|
|
19
|
-
# network interface card and other wackiness. It's sufficiently random for our needs.
|
|
20
|
-
def new_guid
|
|
21
|
-
[8,4,4,4,12].map { |segment_length| random_string(segment_length) }.join('-')
|
|
22
|
-
end
|
|
23
|
-
end
|
data/lib/theatre/invocation.rb
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
require 'theatre/guid'
|
|
2
|
-
require 'thread'
|
|
3
|
-
require 'monitor'
|
|
4
|
-
|
|
5
|
-
module Theatre
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
# An Invocation is an object which Theatre generates and returns from Theatre#trigger.
|
|
9
|
-
#
|
|
10
|
-
class Invocation
|
|
11
|
-
|
|
12
|
-
attr_reader :queued_time, :started_time, :finished_time, :unique_id, :callback, :namespace, :error, :returned_value
|
|
13
|
-
|
|
14
|
-
class InvalidStateError < StandardError; end
|
|
15
|
-
|
|
16
|
-
##
|
|
17
|
-
# Create a new Invocation.
|
|
18
|
-
#
|
|
19
|
-
# @param [String] namespace The "/foo/bar/qaz" path to the namespace to which this Invocation belongs.
|
|
20
|
-
# @param [Proc] callback The block which should be executed by an Actor scheduler.
|
|
21
|
-
# @param [Object] payload The message that will be sent to the callback for processing.
|
|
22
|
-
#
|
|
23
|
-
def initialize(namespace, callback, payload=:theatre_no_payload)
|
|
24
|
-
raise ArgumentError, "Callback must be a Proc" unless callback.kind_of? Proc
|
|
25
|
-
@namespace = namespace
|
|
26
|
-
@callback = callback
|
|
27
|
-
@payload = payload
|
|
28
|
-
@unique_id = new_guid.freeze
|
|
29
|
-
@current_state = :new
|
|
30
|
-
@state_lock = Mutex.new
|
|
31
|
-
|
|
32
|
-
# Used just to protect access to the @returned_value instance variable
|
|
33
|
-
@returned_value_lock = Monitor.new
|
|
34
|
-
|
|
35
|
-
# Used when wait() is called to notify all waiting threads by using a ConditionVariable
|
|
36
|
-
@returned_value_blocker = @returned_value_lock.new_cond#Monitor::ConditionVariable.new @returned_value_lock
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def queued
|
|
40
|
-
with_state_lock do
|
|
41
|
-
raise InvalidStateError unless @current_state == :new
|
|
42
|
-
@current_state = :queued
|
|
43
|
-
@queued_time = Time.now.freeze
|
|
44
|
-
end
|
|
45
|
-
true
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def current_state
|
|
49
|
-
with_state_lock { @current_state }
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def start
|
|
53
|
-
with_state_lock do
|
|
54
|
-
raise InvalidStateError unless @current_state == :queued
|
|
55
|
-
@current_state = :running
|
|
56
|
-
end
|
|
57
|
-
@started_time = Time.now.freeze
|
|
58
|
-
|
|
59
|
-
begin
|
|
60
|
-
self.returned_value = if @payload.equal? :theatre_no_payload
|
|
61
|
-
@callback.call
|
|
62
|
-
else
|
|
63
|
-
@callback.call @payload
|
|
64
|
-
end
|
|
65
|
-
with_state_lock { @current_state = :success }
|
|
66
|
-
rescue => e
|
|
67
|
-
if Array(@namespace).first =~ /exception/
|
|
68
|
-
# Exception encountered in exception handler. Do not perpetuate the loop.
|
|
69
|
-
ahn_log.error "Exception encountered in exception handler!"
|
|
70
|
-
ahn_log.error e.message
|
|
71
|
-
ahn_log.error e.backtrace.join("\n")
|
|
72
|
-
else
|
|
73
|
-
Adhearsion::Events.trigger('/exception', e)
|
|
74
|
-
end
|
|
75
|
-
@error = e
|
|
76
|
-
with_state_lock { @current_state = :error }
|
|
77
|
-
ensure
|
|
78
|
-
@finished_time = Time.now.freeze
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def execution_duration
|
|
83
|
-
return nil unless @finished_time
|
|
84
|
-
@finished_time - @started_time
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def error?
|
|
88
|
-
current_state.equal? :error
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def success?
|
|
92
|
-
current_state.equal? :success
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
##
|
|
96
|
-
# When this Invocation has been queued, started, and entered either the :success or :error state, this method will
|
|
97
|
-
# finally return. Until then, it blocks the Thread.
|
|
98
|
-
#
|
|
99
|
-
# @return [Object] The result of invoking this Invocation's callback
|
|
100
|
-
#
|
|
101
|
-
def wait
|
|
102
|
-
with_returned_value_lock { return @returned_value if defined? @returned_value }
|
|
103
|
-
@returned_value_blocker.wait
|
|
104
|
-
# Return the returned_value
|
|
105
|
-
with_returned_value_lock { @returned_value }
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
protected
|
|
109
|
-
|
|
110
|
-
##
|
|
111
|
-
# Protected setter which does some other housework when the returned value is found (such as notifying wait()ers)
|
|
112
|
-
#
|
|
113
|
-
# @param [returned_value] The value to set this returned value to.
|
|
114
|
-
#
|
|
115
|
-
def returned_value=(returned_value)
|
|
116
|
-
with_returned_value_lock do
|
|
117
|
-
@returned_value = returned_value
|
|
118
|
-
@returned_value_blocker.broadcast
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def with_returned_value_lock(&block)
|
|
123
|
-
@returned_value_lock.synchronize(&block)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def with_state_lock(&block)
|
|
127
|
-
@state_lock.synchronize(&block)
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
end
|
|
131
|
-
end
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
module Theatre
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
# Manages the hierarchial namespaces of a Theatre. This class is Thread-safe.
|
|
5
|
-
#
|
|
6
|
-
class ActorNamespaceManager
|
|
7
|
-
|
|
8
|
-
VALID_NAMESPACE = %r{^(/[\w_]+)+$}
|
|
9
|
-
|
|
10
|
-
class << self
|
|
11
|
-
def valid_namespace_path?(namespace_path)
|
|
12
|
-
namespace_path =~ VALID_NAMESPACE
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
##
|
|
16
|
-
# Since there are a couple ways to represent namespaces, this is a helper method which will normalize
|
|
17
|
-
# them into the most practical: an Array of Symbols
|
|
18
|
-
# @param [String, Array] paths The namespace to register. Can be in "/foo/bar" or *[foo,bar] format
|
|
19
|
-
def normalize_path_to_array(paths)
|
|
20
|
-
paths = paths.is_a?(Array) ? paths.flatten : Array(paths)
|
|
21
|
-
paths.map! { |path_segment| path_segment.kind_of?(String) ? path_segment.split('/') : path_segment }
|
|
22
|
-
paths.flatten!
|
|
23
|
-
paths.reject! { |path| path.nil? || (path.kind_of?(String) && path.empty?) }
|
|
24
|
-
paths.map { |path| path.to_sym }
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def initialize
|
|
30
|
-
@registry_lock = Mutex.new
|
|
31
|
-
@root = RootNamespaceNode.new
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
##
|
|
35
|
-
# Have this registry recognize a new path and prepare it for callback registrations. All path segements will be created
|
|
36
|
-
# in order. For example, when registering "/foo/bar/qaz" when no namespaces at all have been registered, this method will
|
|
37
|
-
# first register "foo", then "bar", then "qaz". If the namespace was already registered, it will not be affected.
|
|
38
|
-
#
|
|
39
|
-
# @param [String, Array] paths The namespace to register. Can be in "/foo/bar" or *[foo,bar] format
|
|
40
|
-
# @return [NamespaceNode] The NamespaceNode representing the path given.
|
|
41
|
-
# @raise NamespaceNotFound if a segment has not been registered yet
|
|
42
|
-
#
|
|
43
|
-
def register_namespace_name(*paths)
|
|
44
|
-
paths = self.class.normalize_path_to_array paths
|
|
45
|
-
|
|
46
|
-
paths.inject(@root) do |node, name|
|
|
47
|
-
node.register_namespace_name name
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
##
|
|
52
|
-
# Returns a Proc found after searching with the namespace you provide
|
|
53
|
-
#
|
|
54
|
-
# @raise NamespaceNotFound if a segment has not been registered yet
|
|
55
|
-
#
|
|
56
|
-
def callbacks_for_namespaces(*paths)
|
|
57
|
-
search_for_namespace(paths).callbacks
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
##
|
|
61
|
-
# Find a namespace in the tree.
|
|
62
|
-
#
|
|
63
|
-
# @param [Array, String] paths Must be an Array of segments or a name like "/foo/bar/qaz"
|
|
64
|
-
# @raise NamespaceNotFound if a segment has not been registered yet
|
|
65
|
-
#
|
|
66
|
-
def search_for_namespace(paths)
|
|
67
|
-
paths = self.class.normalize_path_to_array paths
|
|
68
|
-
path_string = "/"
|
|
69
|
-
|
|
70
|
-
found_namespace = paths.inject(@root) do |last_node,this_node_name|
|
|
71
|
-
raise NamespaceNotFound.new(path_string) if last_node.nil?
|
|
72
|
-
path_string << this_node_name.to_s
|
|
73
|
-
last_node.child_named this_node_name
|
|
74
|
-
end
|
|
75
|
-
raise NamespaceNotFound.new("/#{paths.join('/')}") unless found_namespace
|
|
76
|
-
found_namespace
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
##
|
|
80
|
-
# Registers the given callback at a namespace, assuming the namespace was already registered.
|
|
81
|
-
#
|
|
82
|
-
# @param [Array] paths Must be an Array of segments
|
|
83
|
-
# @param [Proc] callback
|
|
84
|
-
# @raise NamespaceNotFound if a segment has not been registered yet
|
|
85
|
-
#
|
|
86
|
-
def register_callback_at_namespace(paths, callback)
|
|
87
|
-
raise ArgumentError, "callback must be a Proc" unless callback.kind_of? Proc
|
|
88
|
-
search_for_namespace(paths).register_callback callback
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
protected
|
|
92
|
-
|
|
93
|
-
##
|
|
94
|
-
# Used by NamespaceManager to build a tree of namespaces. Has a Hash of children which is not
|
|
95
|
-
# Thread-safe. For Thread-safety, all access should semaphore through the NamespaceManager.
|
|
96
|
-
class NamespaceNode
|
|
97
|
-
|
|
98
|
-
attr_reader :name
|
|
99
|
-
def initialize(name)
|
|
100
|
-
@name = name.freeze
|
|
101
|
-
@children = {}
|
|
102
|
-
@callbacks = []
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def register_namespace_name(name)
|
|
106
|
-
@children[name] ||= NamespaceNode.new(name)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def register_callback(callback)
|
|
110
|
-
@callbacks << callback
|
|
111
|
-
callback
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def callbacks
|
|
115
|
-
@callbacks.clone
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def delete_callback(callback)
|
|
119
|
-
@callbacks.delete callback
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def child_named(name)
|
|
123
|
-
@children[name]
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def destroy_namespace(name)
|
|
127
|
-
@children.delete name
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def root?
|
|
131
|
-
false
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
class RootNamespaceNode < NamespaceNode
|
|
137
|
-
def initialize
|
|
138
|
-
super :ROOT
|
|
139
|
-
end
|
|
140
|
-
def root?
|
|
141
|
-
true
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
class NamespaceNotFound < StandardError
|
|
148
|
-
def initialize(full_path)
|
|
149
|
-
super "Could not find #{full_path.inspect} in the namespace registry. Did you register it yet?"
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
end
|
data/lib/theatre/version.rb
DELETED
data/spec/adhearsion/cli_spec.rb
DELETED
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'adhearsion/cli'
|
|
3
|
-
|
|
4
|
-
module AhnCommandSpecHelper
|
|
5
|
-
|
|
6
|
-
def simulate_args(*args)
|
|
7
|
-
ARGV.clear
|
|
8
|
-
ARGV.concat args
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def capture_stdout(&block)
|
|
12
|
-
old = $stdout
|
|
13
|
-
$stdout = io = StringIO.new
|
|
14
|
-
yield
|
|
15
|
-
ensure
|
|
16
|
-
$stdout = old
|
|
17
|
-
return io.string
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def new_tmp_dir(filename=new_guid)
|
|
21
|
-
File.join Dir.tmpdir, filename
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def create_component_sandbox
|
|
25
|
-
new_tmp_dir.tap do |dir|
|
|
26
|
-
Dir.mkdir dir
|
|
27
|
-
FileUtils.touch dir + "/.ahnrc"
|
|
28
|
-
Dir.mkdir dir + "/components"
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def execute_ahn_command
|
|
33
|
-
Adhearsion::CLI::AhnCommand.execute!
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def executing_ahn_command_should_fail_with(exception)
|
|
37
|
-
flexmock(Adhearsion::CLI::AhnCommand).should_receive(:fail_and_print_usage).with(exception).once
|
|
38
|
-
execute_ahn_command
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
describe 'The Ahn Command helper' do
|
|
44
|
-
|
|
45
|
-
include AhnCommandSpecHelper
|
|
46
|
-
|
|
47
|
-
it "args are simulated properly" do
|
|
48
|
-
before = ARGV.clone
|
|
49
|
-
simulate_args "create", "/tmp/blah"
|
|
50
|
-
ARGV.should_not be before
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it "STDOUT should be captured" do
|
|
54
|
-
capture_stdout do
|
|
55
|
-
puts "wee"
|
|
56
|
-
end.should == "wee\n"
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
describe "A simulated use of the 'ahn' command" do
|
|
62
|
-
|
|
63
|
-
include AhnCommandSpecHelper
|
|
64
|
-
|
|
65
|
-
it "USAGE is defined" do
|
|
66
|
-
Adhearsion::CLI::AhnCommand.const_defined?('USAGE').should be true
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
before do
|
|
70
|
-
flexmock Adhearsion::ScriptAhnLoader, :in_ahn_application? => true
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
it "arguments to 'create' are executed properly" do
|
|
74
|
-
some_path = "/path/somewhere"
|
|
75
|
-
simulate_args "create", some_path
|
|
76
|
-
flexmock(Adhearsion::CLI::AhnCommand::CommandHandler).should_receive(:create).once.with(some_path)
|
|
77
|
-
capture_stdout { Adhearsion::CLI::AhnCommand.execute! }
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
it "arguments to 'start' are executed properly properly" do
|
|
81
|
-
some_path = "/tmp/blargh"
|
|
82
|
-
simulate_args "start", some_path
|
|
83
|
-
flexmock(Adhearsion::CLI::AhnCommand::CommandHandler).should_receive(:start).once.with(some_path, :foreground, nil)
|
|
84
|
-
Adhearsion::CLI::AhnCommand.execute!
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
it "should execute arguments to 'start' for daemonizing properly" do
|
|
88
|
-
somewhere = "/tmp/blarghh"
|
|
89
|
-
simulate_args "start", 'daemon', somewhere
|
|
90
|
-
flexmock(Adhearsion::CLI::AhnCommand::CommandHandler).should_receive(:start).once.with(somewhere, :daemon, nil)
|
|
91
|
-
Adhearsion::CLI::AhnCommand.execute!
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
it "should execute arguments to 'start' for using a console properly" do
|
|
95
|
-
somewhere = "/tmp/blarghh"
|
|
96
|
-
simulate_args "start", 'console', somewhere
|
|
97
|
-
flexmock(Adhearsion::CLI::AhnCommand::CommandHandler).should_receive(:start).once.with(somewhere, :console, nil)
|
|
98
|
-
Adhearsion::CLI::AhnCommand.execute!
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
it 'parse_arguments should recognize start with daemon properly' do
|
|
102
|
-
path = '/path/to/somesuch'
|
|
103
|
-
arguments = ['start', 'daemon', path]
|
|
104
|
-
Adhearsion::CLI::AhnCommand.parse_arguments(arguments).should == [:start, path, :daemon, nil]
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
it 'should not allow both daemon and console to be specified' do
|
|
108
|
-
path = '/path/to/somesuch'
|
|
109
|
-
arguments = ['start', 'daemon', 'console', path]
|
|
110
|
-
lambda { Adhearsion::CLI::AhnCommand.parse_arguments(arguments) }.should raise_error Adhearsion::CLI::AhnCommand::CommandHandler::CLIException
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
it 'should recognize start with daemon and pid file properly' do
|
|
114
|
-
project_path = '/second/star/on/the/right'
|
|
115
|
-
pid_file_path = '/straight/on/til/morning'
|
|
116
|
-
arguments = ["start", "daemon", project_path, "--pid-file=#{pid_file_path}"]
|
|
117
|
-
Adhearsion::CLI::AhnCommand.parse_arguments(arguments).should == [:start, project_path, :daemon, pid_file_path]
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
it 'should recognize start without daemon and with pid file properly' do
|
|
121
|
-
project_path = '/second/star/on/the/right'
|
|
122
|
-
pid_file_path = '/straight/on/til/morning'
|
|
123
|
-
arguments = ["start", project_path, "--pid-file=#{pid_file_path}"]
|
|
124
|
-
Adhearsion::CLI::AhnCommand.parse_arguments(arguments).should == [:start, project_path, :foreground, pid_file_path]
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
it 'parse_arguments should recognize start without daemon properly' do
|
|
128
|
-
path = '/path/to/somewhere'
|
|
129
|
-
arguments = ['start', path]
|
|
130
|
-
Adhearsion::CLI::AhnCommand.parse_arguments(arguments).should == [:start, path, :foreground, nil]
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
it "if no path is provided, running Ahn command blows up" do
|
|
134
|
-
lambda { Adhearsion::CLI::AhnCommand.parse_arguments(['start']) }.should raise_error Adhearsion::CLI::AhnCommand::CommandHandler::CLIException
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
it "printing the version" do
|
|
138
|
-
capture_stdout do
|
|
139
|
-
simulate_args 'version'
|
|
140
|
-
Adhearsion::CLI::AhnCommand.execute!
|
|
141
|
-
end.should =~ Regexp.new(Regexp.escape(Adhearsion::VERSION::STRING))
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
it "printing the help" do
|
|
145
|
-
capture_stdout do
|
|
146
|
-
simulate_args 'help'
|
|
147
|
-
Adhearsion::CLI::AhnCommand.execute!
|
|
148
|
-
end.should =~ Regexp.new(Regexp.escape(Adhearsion::CLI::AhnCommand::USAGE))
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
it "reacting to unrecognized commands" do
|
|
152
|
-
simulate_args "alpha", "beta"
|
|
153
|
-
flexmock(Adhearsion::CLI::AhnCommand).should_receive(:fail_and_print_usage).once.and_return
|
|
154
|
-
Adhearsion::CLI::AhnCommand.execute!
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
it "giving a path that doesn't contain a project raises an exception" do
|
|
158
|
-
simulate_args "start", "/asjdfas/sndjfabsdfbqwb/qnjwejqbwh"
|
|
159
|
-
executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::PathInvalid
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
describe "Component-related commands" do
|
|
165
|
-
|
|
166
|
-
include AhnCommandSpecHelper
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
it "should move a folder from the components/disabled/ folder of an app to the components/ directory if it exists" do
|
|
170
|
-
sandbox = create_component_sandbox
|
|
171
|
-
disabled_dir = "#{sandbox}/components/disabled/foobar"
|
|
172
|
-
enabled_dir = "#{sandbox}/components/foobar"
|
|
173
|
-
|
|
174
|
-
FileUtils.mkdir_p disabled_dir
|
|
175
|
-
FileUtils.touch disabled_dir + "/foobar.rb"
|
|
176
|
-
|
|
177
|
-
flexmock(Dir).should_receive(:pwd).once.and_return disabled_dir
|
|
178
|
-
|
|
179
|
-
simulate_args "enable", "component", "foobar"
|
|
180
|
-
capture_stdout { execute_ahn_command }
|
|
181
|
-
|
|
182
|
-
File.directory?(disabled_dir).should_not be true
|
|
183
|
-
File.exists?(enabled_dir + "/foobar.rb").should be true
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
it "should raise a ComponentError exception if there is no disabled folder" do
|
|
187
|
-
sandbox = create_component_sandbox
|
|
188
|
-
|
|
189
|
-
flexmock(Dir).should_receive(:pwd).once.and_return sandbox
|
|
190
|
-
|
|
191
|
-
simulate_args "enable", "component", "foo"
|
|
192
|
-
|
|
193
|
-
executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::ComponentError
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
it "should raise an exception if the disabled component exists and there's an enabled component of the same name" do
|
|
197
|
-
sandbox = create_component_sandbox
|
|
198
|
-
|
|
199
|
-
flexmock(Dir).should_receive(:pwd).once.and_return sandbox
|
|
200
|
-
|
|
201
|
-
FileUtils.mkdir_p sandbox + "/disabled/lolcats"
|
|
202
|
-
FileUtils.mkdir_p sandbox + "/lolcats"
|
|
203
|
-
|
|
204
|
-
simulate_args "enable", "component", "foo"
|
|
205
|
-
|
|
206
|
-
executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::ComponentError
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
it "should raise a PathInvalid error if the current directory does not belong to an Adhearsion app" do
|
|
210
|
-
flexmock(Dir).should_receive("pwd").and_return "/"
|
|
211
|
-
simulate_args "enable", "component", "foo"
|
|
212
|
-
executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::PathInvalid
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
it "should properly create the disabled folder if it doesn't exist when disabling a component" do
|
|
216
|
-
sandbox = create_component_sandbox
|
|
217
|
-
flexmock(Dir).should_receive(:pwd).once.and_return sandbox
|
|
218
|
-
|
|
219
|
-
FileUtils.mkdir_p sandbox + "/components/rickroller"
|
|
220
|
-
|
|
221
|
-
simulate_args 'disable', 'component', 'rickroller'
|
|
222
|
-
capture_stdout { execute_ahn_command }
|
|
223
|
-
File.directory?(sandbox + "/components/disabled/rickroller").should be true
|
|
224
|
-
File.directory?(sandbox + "/components/rickroller").should be false
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
it "should raise an UnknownCommand error when trying to enable a kind of feature which doesn't exist" do
|
|
228
|
-
simulate_args "enable", "bonobo"
|
|
229
|
-
executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::UnknownCommand
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
it "should raise an UnknownCommand error when trying to disable a kind of feature which doesn't exist" do
|
|
233
|
-
simulate_args "disable", "thanksgiving_dinner"
|
|
234
|
-
executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::UnknownCommand
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
it "should raise a ComponentError when the component to disable doesn't exist" do
|
|
238
|
-
sandbox = create_component_sandbox
|
|
239
|
-
flexmock(Dir).should_receive(:pwd).once.and_return sandbox
|
|
240
|
-
|
|
241
|
-
simulate_args "disable", "component", "monkeybars"
|
|
242
|
-
executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::ComponentError
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
it "should raise an exception when disabling a component and the component's disabled directory already exists" do
|
|
246
|
-
sandbox = create_component_sandbox
|
|
247
|
-
|
|
248
|
-
flexmock(Dir).should_receive(:pwd).once.and_return sandbox
|
|
249
|
-
|
|
250
|
-
FileUtils.mkdir_p sandbox + "/disabled/lolcats"
|
|
251
|
-
FileUtils.mkdir_p sandbox + "/lolcats"
|
|
252
|
-
|
|
253
|
-
simulate_args "disable", "component", "foo"
|
|
254
|
-
executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::ComponentError
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
describe 'The "create" command' do
|
|
260
|
-
|
|
261
|
-
include AhnCommandSpecHelper
|
|
262
|
-
|
|
263
|
-
it "creating a project" do
|
|
264
|
-
the_following_code {
|
|
265
|
-
tmp_path = new_tmp_dir
|
|
266
|
-
simulate_args "create", tmp_path
|
|
267
|
-
# capture_stdout { Adhearsion::CLI::AhnCommand.execute! }
|
|
268
|
-
execute_ahn_command
|
|
269
|
-
File.exists?(File.join(tmp_path, ".ahnrc")).should be true
|
|
270
|
-
}.should_not raise_error
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
it "should raise an UnknownCommand if running create with no arguments" do
|
|
274
|
-
simulate_args "create"
|
|
275
|
-
executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::UnknownCommand
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
it "should raise a ComponentError if the name of the component is not a valid Ruby symbol name" do
|
|
279
|
-
bad_names = ["!))", "37signals", "foo bar", "*"]
|
|
280
|
-
bad_names.each do |bad_name|
|
|
281
|
-
simulate_args "create", "component", bad_name
|
|
282
|
-
executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::ComponentError
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
it "should raise a ComponentError if the component name already exists in the folder" do
|
|
287
|
-
sandbox = create_component_sandbox
|
|
288
|
-
Dir.mkdir sandbox + "/components/blehhh"
|
|
289
|
-
flexmock(Dir).should_receive(:pwd).once.and_return sandbox
|
|
290
|
-
simulate_args "create", "component", "blehhh"
|
|
291
|
-
|
|
292
|
-
executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::ComponentError
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
it "should create a folder with matching .rb file and .yml file when all guards pass" do
|
|
296
|
-
sandbox = create_component_sandbox
|
|
297
|
-
flexmock(Dir).should_receive(:pwd).once.and_return sandbox
|
|
298
|
-
|
|
299
|
-
simulate_args "create", "component", "ohai"
|
|
300
|
-
capture_stdout { execute_ahn_command }
|
|
301
|
-
|
|
302
|
-
File.exists?(sandbox + "/components/ohai/lib/ohai.rb").should be true
|
|
303
|
-
File.exists?(sandbox + "/components/ohai/config/ohai.yml").should be true
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
end
|