Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémy Coutable <remy@rymai.me>2016-06-30 18:34:19 +0300
committerRémy Coutable <remy@rymai.me>2016-08-13 01:05:57 +0300
commit0eea8c885743575b0e93a98846b3663e9903aa66 (patch)
tree9b1903bcb03789d15ed255b76be5d683f3b1e547 /spec/lib/gitlab/slash_commands
parent11eefba891f214eefc1efa334adbcc9e979c0ce3 (diff)
Support slash commands in noteable description and notes
Some important things to note: - commands are removed from noteable.description / note.note - commands are translated to params so that they are treated as normal params in noteable Creation services - the logic is not in the models but in the Creation services, which is the right place for advanced logic that has nothing to do with what models should be responsible of! - UI/JS needs to be updated to handle notes which consist of commands only - the `/merge` command is not handled yet Other improvements: - Don't process commands in commit notes and display a flash is note is only commands - Add autocomplete for slash commands - Add description and params to slash command DSL methods - Ensure replying by email with a commands-only note works - Use :subscription_event instead of calling noteable.subscribe - Support :todo_event in IssuableBaseService Signed-off-by: Rémy Coutable <remy@rymai.me>
Diffstat (limited to 'spec/lib/gitlab/slash_commands')
-rw-r--r--spec/lib/gitlab/slash_commands/dsl_spec.rb110
-rw-r--r--spec/lib/gitlab/slash_commands/extractor_spec.rb177
2 files changed, 287 insertions, 0 deletions
diff --git a/spec/lib/gitlab/slash_commands/dsl_spec.rb b/spec/lib/gitlab/slash_commands/dsl_spec.rb
new file mode 100644
index 00000000000..f8abb35674d
--- /dev/null
+++ b/spec/lib/gitlab/slash_commands/dsl_spec.rb
@@ -0,0 +1,110 @@
+require 'spec_helper'
+
+describe Gitlab::SlashCommands::Dsl do
+ before :all do
+ DummyClass = Class.new do
+ include Gitlab::SlashCommands::Dsl
+
+ desc 'A command with no args'
+ command :no_args, :none do
+ "Hello World!"
+ end
+
+ desc 'A command returning a value'
+ command :returning do
+ return 42
+ end
+
+ params 'The first argument'
+ command :one_arg, :once, :first do |arg1|
+ arg1
+ end
+
+ desc 'A command with two args'
+ params 'The first argument', 'The second argument'
+ command :two_args do |arg1, arg2|
+ [arg1, arg2]
+ end
+
+ command :wildcard do |*args|
+ args
+ end
+ end
+ end
+ let(:dummy) { DummyClass.new }
+
+ describe '.command_definitions' do
+ it 'returns an array with commands definitions' do
+ expected = [
+ { name: :no_args, aliases: [:none], description: 'A command with no args', params: [] },
+ { name: :returning, aliases: [], description: 'A command returning a value', params: [] },
+ { name: :one_arg, aliases: [:once, :first], description: '', params: ['The first argument'] },
+ { name: :two_args, aliases: [], description: 'A command with two args', params: ['The first argument', 'The second argument'] },
+ { name: :wildcard, aliases: [], description: '', params: [] }
+ ]
+
+ expect(DummyClass.command_definitions).to eq expected
+ end
+ end
+
+ describe '.command_names' do
+ it 'returns an array with commands definitions' do
+ expect(DummyClass.command_names).to eq [
+ :no_args, :none, :returning, :one_arg,
+ :once, :first, :two_args, :wildcard
+ ]
+ end
+ end
+
+ describe 'command with no args' do
+ context 'called with no args' do
+ it 'succeeds' do
+ expect(dummy.__send__(:no_args)).to eq 'Hello World!'
+ end
+ end
+ end
+
+ describe 'command with an explicit return' do
+ context 'called with no args' do
+ it 'succeeds' do
+ expect(dummy.__send__(:returning)).to eq 42
+ end
+ end
+ end
+
+ describe 'command with one arg' do
+ context 'called with one arg' do
+ it 'succeeds' do
+ expect(dummy.__send__(:one_arg, 42)).to eq 42
+ end
+ end
+ end
+
+ describe 'command with two args' do
+ context 'called with two args' do
+ it 'succeeds' do
+ expect(dummy.__send__(:two_args, 42, 'foo')).to eq [42, 'foo']
+ end
+ end
+ end
+
+ describe 'command with wildcard' do
+ context 'called with no args' do
+ it 'succeeds' do
+ expect(dummy.__send__(:wildcard)).to eq []
+ end
+ end
+
+ context 'called with one arg' do
+ it 'succeeds' do
+ expect(dummy.__send__(:wildcard, 42)).to eq [42]
+ end
+ end
+
+ context 'called with two args' do
+ it 'succeeds' do
+ expect(dummy.__send__(:wildcard, 42, 'foo')).to eq [42, 'foo']
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/slash_commands/extractor_spec.rb b/spec/lib/gitlab/slash_commands/extractor_spec.rb
new file mode 100644
index 00000000000..fd1b30052ed
--- /dev/null
+++ b/spec/lib/gitlab/slash_commands/extractor_spec.rb
@@ -0,0 +1,177 @@
+require 'spec_helper'
+
+describe Gitlab::SlashCommands::Extractor do
+ let(:extractor) { described_class.new([:open, :assign, :labels, :power]) }
+
+ shared_examples 'command with no argument' do
+ it 'extracts command' do
+ commands = extractor.extract_commands!(original_msg)
+
+ expect(commands).to eq [['open']]
+ expect(original_msg).to eq final_msg
+ end
+ end
+
+ shared_examples 'command with a single argument' do
+ it 'extracts command' do
+ commands = extractor.extract_commands!(original_msg)
+
+ expect(commands).to eq [['assign', '@joe']]
+ expect(original_msg).to eq final_msg
+ end
+ end
+
+ shared_examples 'command with multiple arguments' do
+ it 'extracts command' do
+ commands = extractor.extract_commands!(original_msg)
+
+ expect(commands).to eq [['labels', '~foo ~"bar baz" label']]
+ expect(original_msg).to eq final_msg
+ end
+ end
+
+ describe '#extract_commands!' do
+ describe 'command with no argument' do
+ context 'at the start of content' do
+ it_behaves_like 'command with no argument' do
+ let(:original_msg) { "/open\nworld" }
+ let(:final_msg) { "world" }
+ end
+ end
+
+ context 'in the middle of content' do
+ it_behaves_like 'command with no argument' do
+ let(:original_msg) { "hello\n/open\nworld" }
+ let(:final_msg) { "hello\nworld" }
+ end
+ end
+
+ context 'in the middle of a line' do
+ it 'does not extract command' do
+ msg = "hello\nworld /open"
+ commands = extractor.extract_commands!(msg)
+
+ expect(commands).to be_empty
+ expect(msg).to eq "hello\nworld /open"
+ end
+ end
+
+ context 'at the end of content' do
+ it_behaves_like 'command with no argument' do
+ let(:original_msg) { "hello\n/open" }
+ let(:final_msg) { "hello\n" }
+ end
+ end
+ end
+
+ describe 'command with a single argument' do
+ context 'at the start of content' do
+ it_behaves_like 'command with a single argument' do
+ let(:original_msg) { "/assign @joe\nworld" }
+ let(:final_msg) { "world" }
+ end
+ end
+
+ context 'in the middle of content' do
+ it_behaves_like 'command with a single argument' do
+ let(:original_msg) { "hello\n/assign @joe\nworld" }
+ let(:final_msg) { "hello\nworld" }
+ end
+ end
+
+ context 'in the middle of a line' do
+ it 'does not extract command' do
+ msg = "hello\nworld /assign @joe"
+ commands = extractor.extract_commands!(msg)
+
+ expect(commands).to be_empty
+ expect(msg).to eq "hello\nworld /assign @joe"
+ end
+ end
+
+ context 'at the end of content' do
+ it_behaves_like 'command with a single argument' do
+ let(:original_msg) { "hello\n/assign @joe" }
+ let(:final_msg) { "hello\n" }
+ end
+ end
+
+ context 'when argument is not separated with a space' do
+ it 'does not extract command' do
+ msg = "hello\n/assign@joe\nworld"
+ commands = extractor.extract_commands!(msg)
+
+ expect(commands).to be_empty
+ expect(msg).to eq "hello\n/assign@joe\nworld"
+ end
+ end
+ end
+
+ describe 'command with multiple arguments' do
+ context 'at the start of content' do
+ it_behaves_like 'command with multiple arguments' do
+ let(:original_msg) { %(/labels ~foo ~"bar baz" label\nworld) }
+ let(:final_msg) { "world" }
+ end
+ end
+
+ context 'in the middle of content' do
+ it_behaves_like 'command with multiple arguments' do
+ let(:original_msg) { %(hello\n/labels ~foo ~"bar baz" label\nworld) }
+ let(:final_msg) { "hello\nworld" }
+ end
+ end
+
+ context 'in the middle of a line' do
+ it 'does not extract command' do
+ msg = %(hello\nworld /labels ~foo ~"bar baz" label)
+ commands = extractor.extract_commands!(msg)
+
+ expect(commands).to be_empty
+ expect(msg).to eq %(hello\nworld /labels ~foo ~"bar baz" label)
+ end
+ end
+
+ context 'at the end of content' do
+ it_behaves_like 'command with multiple arguments' do
+ let(:original_msg) { %(hello\n/labels ~foo ~"bar baz" label) }
+ let(:final_msg) { "hello\n" }
+ end
+ end
+
+ context 'when argument is not separated with a space' do
+ it 'does not extract command' do
+ msg = %(hello\n/labels~foo ~"bar baz" label\nworld)
+ commands = extractor.extract_commands!(msg)
+
+ expect(commands).to be_empty
+ expect(msg).to eq %(hello\n/labels~foo ~"bar baz" label\nworld)
+ end
+ end
+ end
+
+ it 'extracts command with multiple arguments and various prefixes' do
+ msg = %(hello\n/power @user.name %9.10 ~"bar baz.2"\nworld)
+ commands = extractor.extract_commands!(msg)
+
+ expect(commands).to eq [['power', '@user.name %9.10 ~"bar baz.2"']]
+ expect(msg).to eq "hello\nworld"
+ end
+
+ it 'extracts multiple commands' do
+ msg = %(hello\n/power @user.name %9.10 ~"bar baz.2" label\nworld\n/open)
+ commands = extractor.extract_commands!(msg)
+
+ expect(commands).to eq [['power', '@user.name %9.10 ~"bar baz.2" label'], ['open']]
+ expect(msg).to eq "hello\nworld\n"
+ end
+
+ it 'does not alter original content if no command is found' do
+ msg = 'Fixes #123'
+ commands = extractor.extract_commands!(msg)
+
+ expect(commands).to be_empty
+ expect(msg).to eq 'Fixes #123'
+ end
+ end
+end