Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 7
- Log:
Initial import of RForum 0.2 sources from a downloaded Tarball.
RForum is a Ruby On Rails based forum and mail gateway service.
- Author:
- adh
- Date:
- Sat Jul 22 18:43:13 +0100 2006
- Size:
- 5491 Bytes
1 | # Collection of various assertions and other methods, commonly used in Rails unit tests |
2 | |
3 | # To debug a test, put 'bp' anywhere and run the test. |
4 | # It will spawn IRB session at the scope where bp is. |
5 | # Requires either breakpoint or dev-utils package |
6 | begin |
7 | require 'breakpoint' |
8 | rescue LoadError |
9 | begin |
10 | require 'dev-utils/debug' |
11 | rescue LoadError |
12 | begin |
13 | require_gem 'dev-utils' |
14 | rescue |
15 | end |
16 | end |
17 | end |
18 | |
19 | # Shorthand for IRB breakpoint |
20 | alias :bp :breakpoint if defined? Breakpoint |
21 | |
22 | # Assert that an object has all of the listed attributes |
23 | def assert_has_attributes(object, attributes) |
24 | assert object.kind_of?(ActiveRecord::Base) |
25 | assert_nothing_raised { attributes.each { |attr| object.send(attr.to_sym) } } |
26 | end |
27 | |
28 | # Remember start and finish time of a block, then test that a certain field was set to sysdate) |
29 | # Usage: |
30 | # post = time { Post.create(test_inputs) } |
31 | # assert_equal_sysdate post.created_at |
32 | begin |
33 | def time |
34 | @start_time = Time.now |
35 | return yield |
36 | ensure @finish_time = Time.now |
37 | end |
38 | |
39 | def assert_equal_sysdate(value) |
40 | assert value.to_i.between?(@start_time.to_i, @finish_time.to_i), |
41 | "'#{value}' is #{offset_from_sysdate(value)} msec off from the last remembered sysdate" |
42 | end |
43 | |
44 | def offset_from_sysdate(value) |
45 | value.to_i - (@start_time.to_i + @finish_time.to_i) / 2 |
46 | end |
47 | end |
48 | |
49 | # For a given list of attribute names, asserts that all of them are not nullable, |
50 | # and it is enforced by validate |
51 | def assert_mandatory_attributes_enforced(attribute_names, entity_class) |
52 | |
53 | # it should be possible to create a record from prototype_params |
54 | assert_nothing_raised { |
55 | p = entity_class.create(prototype_params(entity_class)) |
56 | } |
57 | attribute_names.each do |
58 | |attr| |
59 | params = prototype_params(entity_class).dup |
60 | params[attr] = nil |
61 | assert_raises(ArgumentError, "Attribute #{attr} can be set to nil") do |
62 | entity_class.new(params).validate |
63 | end |
64 | end |
65 | end |
66 | |
67 | # Asserts that all attributes specified in the attributes_hash have the same value in the ar_object |
68 | def assert_attributes_equal(attributes_hash, ar_object) |
69 | attributes_hash.each_pair { |k, v| |
70 | if k == 'id' and v.nil? |
71 | #skip the check; prototype attributes always include a nil id |
72 | else |
73 | assert_equal v, ar_object[k], "Value of '#{k} attribute is not as expected" |
74 | end |
75 | } |
76 | end |
77 | |
78 | # Extracts attributes from the ar_ibject |
79 | def attributes(ar_object) |
80 | # this doesn't work because internal representation of numbers in AR::Base is strings: |
81 | # ar_object.instance_eval('@attributes').dup |
82 | hash = {} |
83 | ar_object.attribute_names.each { |attr| hash[attr] = ar_object[attr] } |
84 | hash |
85 | end |
86 | |
87 | def assert_validation_fails(clazz, attributes, error_field = nil, expected_message = nil) |
88 | begin |
89 | clazz.create(attributes) |
90 | fail "Validation did not fail" |
91 | rescue RForum::ValidationError => expected |
92 | assert expected.errors[error_field] if error_field |
93 | if expected_message |
94 | assert_equal expected_message, expected.errors[error_field], "Error message not as expected" |
95 | end |
96 | end |
97 | end |
98 | |
99 | # Prototypes are pre-set objects that can be used to create a test fixture quickly |
100 | module FtaPrototypes |
101 | |
102 | PROTOTYPE_ATTRIBUTES = {} |
103 | |
104 | def self.set_prototype(clazz, attributes) |
105 | # prototype attributes should have an 'id' attribute, but it should be nil. |
106 | # This is how it is coming from HTML forms when the same form is reused for creation |
107 | # and editing of an entity. Code that works with attribute hashes must hande this situation |
108 | # correctly. |
109 | attributes['id'] = nil |
110 | |
111 | attributes.each_pair { |key, value| key.freeze; value.freeze } |
112 | attributes.freeze |
113 | PROTOTYPE_ATTRIBUTES[clazz.to_s] = PrototypeAttrs.new(attributes) |
114 | end |
115 | |
116 | def self.set_prototypes(prototypes_hash) |
117 | prototypes_hash.each_pair { |key, value| set_prototype(key, value) } |
118 | end |
119 | |
120 | class PrototypeAttrs < Hash |
121 | def initialize(hash) |
122 | hash.each_pair { |k, v| self[k] = v } |
123 | end |
124 | |
125 | # Deletes attrs from prototype |
126 | # Usage: |
127 | # post = prototype_params(Post).without('l', 'r') |
128 | def without(*attrs) |
129 | attrs.each { |attr| self.delete attr } |
130 | self |
131 | end |
132 | end |
133 | |
134 | end |
135 | |
136 | # Returns an (attributes => values) hash that can be used to create a new object of given class |
137 | # If additional_params is specified, merges them into the hash |
138 | # |
139 | # Usage examples: |
140 | # normal_post = Post.create(prototype_params(Post)) |
141 | # post_with_empty_text = Post.new(prototype_params(Post, 'text' => nil)) |
142 | # errors = prototype_params(Post) { |params| |
143 | # begin; Post.create(params); rescue ValidationError => e; end |
144 | # } |
145 | |
146 | def prototype_params(clazz, additional_params = nil) |
147 | raise "No prototype for #{clazz}" if FtaPrototypes::PROTOTYPE_ATTRIBUTES[clazz.to_s].nil? |
148 | prototype_hash = FtaPrototypes::PROTOTYPE_ATTRIBUTES[clazz.to_s].dup |
149 | if prototype_hash.nil? |
150 | raise "#{clazz.inspect} not found among prototypes " + |
151 | "for #{FtaPrototypes::PROTOTYPE_ATTRIBUTES.keys.collect{|k| k.to_s}.join(', ')}" |
152 | end |
153 | combined_hash = prototype_hash.merge(additional_params ? additional_params : {} ) |
154 | yield combined_hash if block_given? |
155 | combined_hash |
156 | end |
157 | |
158 | # Same as prototype_params above, but returns a result of passing the prototype parameters hash |
159 | # to clazz.new. Also, if a block is given, it receives an object from constructor, not |
160 | # a parameters hash |
161 | def prototype(clazz, additional_params = nil) |
162 | new_object = Object::const_get(clazz.to_s).new(prototype_params(clazz, additional_params)) |
163 | yield new_object if block_given? |
164 | new_object |
165 | end |