sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit ab3ab3b97a9ed517640b53332a9f0be76af94c99
parent a6cfac2d0b8ea7b260f1f103b708fb4f3229bd16
Author: Whyme Lyu <callme5long@gmail.com>
Date:   Sun, 19 May 2013 23:41:40 +0800

Implement LabelService#{add,remove}_labels

Diffstat:
M lib/sup/index.rb | 5 +++++
A lib/sup/service/label_service.rb | 45 +++++++++++++++++++++++++++++++++++++++++++++
A test/integration/test_label_service.rb | 18 ++++++++++++++++++
A test/unit/service/test_label_service.rb | 19 +++++++++++++++++++
4 files changed, 87 insertions(+), 0 deletions(-)
diff --git a/lib/sup/index.rb b/lib/sup/index.rb
@@ -259,6 +259,11 @@ EOS
     end
   end
 
+  # Search messages. Returns an Enumerator.
+  def find_messages query_expr
+    enum_for :each_message, parse_query(query_expr)
+  end
+
   # wrap all future changes inside a transaction so they're done atomically
   def begin_transaction
     synchronize { @xapian.begin_transaction }
diff --git a/lib/sup/service/label_service.rb b/lib/sup/service/label_service.rb
@@ -0,0 +1,45 @@
+require "sup/index"
+
+module Redwood
+  # Provides label tweaking service to the user.
+  # Working as the backend of ConsoleMode.
+  #
+  # Should become the backend of bin/sup-tweak-labels in the future.
+  class LabelService
+    # @param index [Redwood::Index]
+    def initialize index=Index.instance
+      @index = index
+    end
+
+    def add_labels query, *labels
+      run_on_each_message(query) do |m|
+        labels.each {|l| m.add_label l }
+      end
+    end
+
+    def remove_labels query, *labels
+      run_on_each_message(query) do |m|
+        labels.each {|l| m.remove_label l }
+      end
+    end
+
+
+    private
+    def run_on_each_message query, &operation
+      count = 0
+
+      find_messages(query).each do |m|
+        operation.call(m)
+        @index.update_message_state m
+        count += 1
+      end
+
+      @index.save_index
+      count
+    end
+
+    def find_messages query
+      @index.find_messages(query)
+    end
+  end
+end
diff --git a/test/integration/test_label_service.rb b/test/integration/test_label_service.rb
@@ -0,0 +1,18 @@
+require "test_helper"
+
+require "sup/service/label_service"
+
+require "tmpdir"
+
+describe Redwood::LabelService do
+  let(:tmpdir) { Dir.mktmpdir }
+  after do
+    require "fileutils"
+    FileUtils.remove_entry_secure @tmpdir unless @tmpdir.nil?
+  end
+
+  describe "#add_labels" do
+    # Integration tests are hard to write at this moment :(
+    it "add labels to all messages matching the query"
+  end
+end
diff --git a/test/unit/service/test_label_service.rb b/test/unit/service/test_label_service.rb
@@ -0,0 +1,19 @@
+require "test_helper"
+
+require "sup/service/label_service"
+
+describe Redwood::LabelService do
+  describe "#add_labels" do
+    it "add labels to all messages matching the query" do
+      q = 'is:starred'
+      label = 'superstarred'
+      message = mock!.add_label(label).subject
+      index = mock!.find_messages(q){ [message] }.subject
+      mock(index).update_message_state(message)
+      mock(index).save_index
+
+      service = Redwood::LabelService.new(index)
+      service.add_labels q, label
+    end
+  end
+end