Tired of looking at the console to know if the tests passed or failed?

AutoTest (part of ZenTest suite) is a very useful tool when you are working with Ruby On Rails development, but I always had problems configuring cool notifications for it, until now!

A friend of mine, started a little project to develop a gem (his first idea was just a lib for his own use, but now it turned to be an open source gem), that makes really easy to setup AutoTest to notify you of test results in a very cool way!

If you have a Mac, it will use Growl.
If you have windows, it will use Snarl.
If you have a Linux Box, it will use zenity or libnotify for Gnome and kdialog for KDE (I think libnotify works for any desktop environment).

And it is even cooler that this, if you run a Mac or Linux box, it can talk to you when your tests fail!

The project is hosted at GitHub, and to use it, you just need to run this two commands:

gem install carlosbrando-autotest-notification --source=http://gems.github.com
an-install

if you want it to talk to you, replace the last command with:

an-install -s

the voice code for linux is not in the main repository yet, it is on my fork, so if you run a linux box, and want to play with voice notification, you need to have espeak installed, and install my instead of the primary one (at least until the code is pushed back).

gem install urubatan-autotest-notification --source=http://gems.github.com

If you have a Windows box and want to play with voice notification, be a smart guy, format your machine ans install linux, you will be a lot happier that you are today :D
If this is not an option for you, you can always fork the project, write the code for a windows speech engine, and send us a pull request :D

Bellow a quote from the project readme about the dependencies of each platform:

* If you’re using a Mac:
You need to have Growl and growlnotify installed on your machine.

Download the Growl [http://growl.info/index.php] and install it like any other application on your Mac

Then you must install the growlnotify.

In your shell, cd to the directory on the Growl disk image containing growlnotify, and type ./install.sh.
That script will install growlnotify to /usr/local/bin and the manpage to /usr/local/man.

* If you’re using Windows (with cygwin):
You need to have Snarl and sncmd installed on your machine.

Download Snarl [http://www.fullphat.net/] and install it like any other application on your machine.

Then download sncmd [http://www.k23productions.com/download.php?view.105] open the zip file and place
the executable from the zip in any directory in windows PATH (for example c:\windows).

* If you’re using Windows (without cygwin):
You need to have Snarl, diffutils and ruby-snarl installed on your machine.

Download Snarl [http://www.fullphat.net/] and install it like any other application on your machine.

Download DiffUtils for Windows [http://gnuwin32.sourceforge.net/packages/diffutils.htm] and follow the installation
instructions on the site.

Run in the command prompt:

$ gem install ruby-snarl

After all that. You must update the environment variable PATH with the path to the bin of diffutils.
It’s the price that was paid for using Windows (try cygwin).

* If you’re using Linux:
You need to have libnotify binaries installed.

For ubuntu this means: sudo apt-get install libnotify-bin

Other distributions may package it with other names, do a search for libnotify using your distribution package
manager.

If you use KDE and do not have libnotify-bin installed, it will try to use kdialog wich is part of KDE.
It also works if you have zenity installed.

If you want to be notified with voice of the test results, instal espeak too, it is not needed.
And when running an-install, pass a “-s” switch, when you do not want voices notifications anymore, just run it
again without the “-s” switch.

I know that you can live without this cool new toy, but think about your work mates trying to figure out, how do your computer can tell you that your tests passed or not :D

If you enjoyed this post, make sure you subscribe to my RSS feed!

GEdit plugin for formatting ruby code


I work with Java for a long time, and I’m used to Eclipse facilities, but to work with ruby on rails I think an IDE is not needed, I work better with GEdit (or even VIM, depends on my humor) than ith NetBeans or Aptana.
But there are some features of an IDE that I miss when working with GEdit, for example code formatting.
As a heavy eclipse user, I prefer to let eclipse take care of the indentation of my source files …
So I have created this GEdit plugin to format ruby files, if you want to use it, just checkout the source code from GitHub and copy all files to ~/.gnome2/gedit/plugins, restart gedit and you are ready to go …
After reopening GEdit, click Edit\Preferences\plugins and enable the “Code Formatter” plugin.
then, when you are editing a ruby file, just click CTRL+ALT+F and the code will be formatted for you.
if you are more a mouse gui, just click Tools\Format Code.

I hope this plugin can be useful for others too.
I plan to add support for more languages, for example XHTML and RHTML (ERB + XHTML), I know tidy plugin can do this, but I do not like the default tidy configuration, but will probably use tidy as a backend to this feature :D

to checkout the code, you can download the zip file available in the project page, or use git:

git clone git://github.com/urubatan/gedit_formatter.git

Any doubts, problems or tips for improvements just leave a comment, here or in github.

PS.: this was my first GEdit plugin, and my first experience with python, the code can be improved a lot, any comments about that are very welcome.

If you enjoyed this post, make sure you subscribe to my RSS feed!

Dirty models and partial SQL updates for Rails 2.0.2

First of all, this is not my code, this is just a backport of a Rails EDGE feature to work with Rails 2.0.2 …

I searched through Rails code and found the points tha needed some changes to work with rails 2.0.2, and not the only thing you need if you want this features but can’t use EDGE right now, just place this code into a file in the config/initializers (I named it dirty.rb) …

So, let’s stop the cheap talk and show the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
module ActiveRecord
 
  class Base
 
	  # Updates the associated record with values matching those of the instance attributes.
 
	  # Returns the number of affected rows.
 
	  def update(attribute_names = @attributes.keys)
 
		quoted_attributes = attributes_with_quotes(false, false, attribute_names)
 
		return 0 if quoted_attributes.empty?
 
		connection.update(
 
		  "UPDATE #{self.class.quoted_table_name} " +
 
		  "SET #{quoted_comma_pair_list(connection, quoted_attributes)} " +
 
		  "WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quote_value(id)}",
 
		  "#{self.class.name} Update"
 
		)
 
	  end
 
      # Returns a copy of the attributes hash where all the values have been safely quoted for use in
 
     # an SQL statement.
 
     def attributes_with_quotes(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
 
       quoted = {}
 
       connection = self.class.connection
 
       attribute_names.each do |name|
 
         if column = column_for_attribute(name)
 
           quoted[name] = connection.quote(read_attribute(name), column) unless !include_primary_key && column.primary
 
         end
 
       end
 
       include_readonly_attributes ? quoted : remove_readonly_attributes(quoted)
 
     end
 
  end
 
  # Track unsaved attribute changes.
 
  #
 
  # A newly instantiated object is unchanged:
 
  #   person = Person.find_by_name('uncle bob')
 
  #   person.changed?       # => false
 
  #
 
  # Change the name:
 
  #   person.name = 'Bob'
 
  #   person.changed?       # => true
 
  #   person.name_changed?  # => true
 
  #   person.name_was       # => 'uncle bob'
 
  #   person.name_change    # => ['uncle bob', 'Bob']
 
  #   person.name = 'Bill'
 
  #   person.name_change    # => ['uncle bob', 'Bill']
 
  #
 
  # Save the changes:
 
  #   person.save
 
  #   person.changed?       # => false
 
  #   person.name_changed?  # => false
 
  #
 
  # Assigning the same value leaves the attribute unchanged:
 
  #   person.name = 'Bill'
 
  #   person.name_changed?  # => false
 
  #   person.name_change    # => nil
 
  #
 
  # Which attributes have changed?
 
  #   person.name = 'bob'
 
  #   person.changed        # => ['name']
 
  #   person.changes        # => { 'name' => ['Bill', 'bob'] }
 
  #
 
  # Before modifying an attribute in-place:
 
  #   person.name_will_change!
 
  #   person.name << 'by'
 
  #   person.name_change    # => ['uncle bob', 'uncle bobby']
 
  module Dirty
 
    def self.included(base)
 
      base.attribute_method_suffix '_changed?', '_change', '_will_change!', '_was'
 
      base.alias_method_chain :write_attribute, :dirty
 
      base.alias_method_chain :save,            :dirty
 
      base.alias_method_chain :save!,           :dirty
 
      base.alias_method_chain :update,          :dirty
 
 
 
      base.superclass_delegating_accessor :partial_updates
 
      base.partial_updates = true
 
    end
 
 
 
    # Do any attributes have unsaved changes?
 
    #   person.changed? # => false
 
    #   person.name = 'bob'
 
    #   person.changed? # => true
 
    def changed?
 
      !changed_attributes.empty?
 
    end
 
 
 
    # List of attributes with unsaved changes.
 
    #   person.changed # => []
 
    #   person.name = 'bob'
 
    #   person.changed # => ['name']
 
    def changed
 
      changed_attributes.keys
 
    end
 
 
 
    # Map of changed attrs => [original value, new value]
 
    #   person.changes # => {}
 
    #   person.name = 'bob'
 
    #   person.changes # => { 'name' => ['bill', 'bob'] }
 
    def changes
 
      changed.inject({}) { |h, attr| h[attr] = attribute_change(attr); h }
 
    end
 
 
 
 
 
    # Clear changed attributes after they are saved.
 
    def save_with_dirty(*args) #:nodoc:
 
      save_without_dirty(*args)
 
    ensure
 
      changed_attributes.clear
 
    end
 
 
 
    # Clear changed attributes after they are saved.
 
    def save_with_dirty!(*args) #:nodoc:
 
      save_without_dirty!(*args)
 
    ensure
 
      changed_attributes.clear
 
    end
 
 
 
    def self.partial_updates?
 
      @partial_updates
 
    end
 
 
 
    private
 
      # Map of change attr => original value.
 
      def changed_attributes
 
        @changed_attributes ||= {}
 
      end
 
 
 
      # Handle *_changed? for method_missing.
 
      def attribute_changed?(attr)
 
        changed_attributes.include?(attr)
 
      end
 
 
 
      # Handle *_change for method_missing.
 
      def attribute_change(attr)
 
        [changed_attributes[attr], __send__(attr)] if attribute_changed?(attr)
 
      end
 
 
 
      # Handle *_was for method_missing.
 
      def attribute_was(attr)
 
        attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
 
      end
 
 
 
      # Handle *_will_change! for method_missing.
 
      def attribute_will_change!(attr)
 
        changed_attributes[attr] = clone_attribute_value(:read_attribute, attr)
 
      end
 
 
 
      # Wrap write_attribute to remember original attribute value.
 
      def write_attribute_with_dirty(attr, value)
 
        attr = attr.to_s
 
 
 
        # The attribute already has an unsaved change.
 
        unless changed_attributes.include?(attr)
 
          old = clone_attribute_value(:read_attribute, attr)
 
 
 
          # Remember the original value if it's different.
 
          typecasted = if column = column_for_attribute(attr)
 
                         column.type_cast(value)
 
                       else
 
                         value
 
                       end
 
          changed_attributes[attr] = old unless old == typecasted
 
        end
 
 
 
        # Carry on.
 
        write_attribute_without_dirty(attr, value)
 
      end
 
 
 
      def update_with_dirty
 
        update_without_dirty(changed)
 
      end
 
  end
 
end
 
 
 
ActiveRecord::Base.send :include, ActiveRecord::Dirty
 
#ActiveRecord::Base.partial_updates = true -- Now there is no way to disable this ugly partial updates hack

I hope it can be usefull for others too :D
you can see how it works in this posts about rails EDGE.
If you have any problem, just leave a comment.

PS.: yes, it can be cleaned up a little, but it is already working fine for me, and it is just a backport :D

If you enjoyed this post, make sure you subscribe to my RSS feed!