Guards
Version 1 (Federico Builes, 08/24/2008 07:01 PM)
| 1 | 1 | h2. MSpec guards |
|
|---|---|---|---|
| 2 | 1 | ||
| 3 | 1 | h3. platform_is |
|
| 4 | 1 | ||
| 5 | 1 | In some cases, Ruby exhibits different behaviors based on its execution environment. For example, the maximum value of a Fixnum before it is promoted to a Bignum is different in 32-bit and 64-bit platforms. In this cases you can use the |
|
| 6 | 1 | platform_is guard: |
|
| 7 | 1 | ||
| 8 | 1 | ||
| 9 | 1 | platform_is :wordsize => 32 do |
|
| 10 | 1 | it "converts numbers to Bignums if they get too big" do |
|
| 11 | 1 | # 32-bit behaviour goes here |
|
| 12 | 1 | end |
|
| 13 | 1 | end |
|
| 14 | 1 | ||
| 15 | 1 | platform_is_not :os => :windows do |
|
| 16 | 1 | it "runs on a real OS" |
|
| 17 | 1 | # do something... |
|
| 18 | 1 | end |
|
| 19 | 1 | end |
|
| 20 | 1 | ||
| 21 | 1 | ||
| 22 | 1 | This would "do something" on every OS but Windows. |
|
| 23 | 1 | ||
| 24 | 1 | h3. compliant_on/non_compliant_on |
|
| 25 | 1 | ||
| 26 | 1 | Since each Ruby implementation may have its own quirks, you can make use of the @compliant_on/non_compliant_on@ set of guards to make sure that your specs run only on certain implementations: |
|
| 27 | 1 | ||
| 28 | 1 | ||
| 29 | 1 | non_compliant_on :jruby do |
|
| 30 | 1 | # some code that works differently in JRuby |
|
| 31 | 1 | end |
|
| 32 | 1 | ||
| 33 | 1 | ||
| 34 | 1 | Since we're using this project to specify the behavior of MatzRuby (MRI), every @compliant_on@ guard should include @:ruby@ and no @non_compliant_on@ should have it. |
|
| 35 | 1 | ||
| 36 | 1 | h3. ruby_bug |
|
| 37 | 1 | ||
| 38 | 1 | If you know that a certain version of Ruby has a bug and you want to guard against it you can use the @ruby_bug@ guard: |
|
| 39 | 1 | ||
| 40 | 1 | ||
| 41 | 1 | ruby_bug "some_id_number", version do |
|
| 42 | 1 | it "produces 2 when adding 1 to 1" do |
|
| 43 | 1 | # CORRECT implementation goes here |
|
| 44 | 1 | (1 + 1).should == 2 |
|
| 45 | 1 | end |
|
| 46 | 1 | end |
|
| 47 | 1 | ||
| 48 | 1 | ||
| 49 | 1 | In this case, @some_id_number@ is the number of the reported issue in "Ruby's Redmine tracker":http://redmine.ruby-lang.org/ (because you did create an issue for this, right?). @version@ is the Ruby version you want to guard against, for example: |
|
| 50 | 1 | ||
| 51 | 1 | ||
| 52 | 1 | ruby_bug "#1337", 1.8.6.110 do |
|
| 53 | 1 | it "produces 2 when adding 1 to 1" do |
|
| 54 | 1 | (1+1).should == 2 |
|
| 55 | 1 | end |
|
| 56 | 1 | end |
|
| 57 | 1 | ||
| 58 | 1 | ||
| 59 | 1 | In this case the issue was reported in Ruby's Redmine as ticket #1337 and this spec will be ignored when the Ruby version is ruby-1.8.6 patchlevel 110. |
|
| 60 | 1 | ||
| 61 | 1 | h3. ruby_version_is |
|
| 62 | 1 | ||
| 63 | 1 | Sometimes the behavior of certain methods will change between different Ruby versions (or revisions). If you're writing specs against several patchlevels or releases you can use the @ruby_version_is@ guard: |
|
| 64 | 1 | ||
| 65 | 1 | ||
| 66 | 1 | ruby_version_is "" ... "1.9" do |
|
| 67 | 1 | it "adds two numbers" do |
|
| 68 | 1 | (1+1).should == 2 |
|
| 69 | 1 | end |
|
| 70 | 1 | end |
|
| 71 | 1 | ||
| 72 | 1 | ruby_version_is "1.9" do |
|
| 73 | 1 | it "adds two numbers" do |
|
| 74 | 1 | (1+1).should == 3 |
|
| 75 | 1 | end |
|
| 76 | 1 | end |
|
| 77 | 1 | ||
| 78 | 1 | ||
| 79 | 1 | In this case we're assuming that 1 + 1 will equal 2 in every version *before* 1.9 and that in 1.9 and *following* versions it will return 3. |
|
| 80 | 1 | ||
| 81 | 1 | h3. big_endian/little_endian |
|
| 82 | 1 | ||
| 83 | 1 | h3. as_superuser |
|
| 84 | 1 | ||
| 85 | 1 | If you need to make sure that you're root before running some of your specs you can use the @as_superuser@ guard: |
|
| 86 | 1 | ||
| 87 | 1 | ||
| 88 | 1 | as_superuser do |
|
| 89 | 1 | it "is dangerous" do |
|
| 90 | 1 | FileUtils.rm_rf("/") |
|
| 91 | 1 | end |
|
| 92 | 1 | end |
|
| 93 | 1 | ||
| 94 | 1 | ||
| 95 | 1 | If the user running the specs is not root (UID = 0) the specs will be ignored. |
|
| 96 | 1 | ||
| 97 | 1 | h3. not_supported_on |
|
| 98 | 1 | ||
| 99 | 1 | If a Ruby implementation does not support a certain feature (and probably won't support it in the future) you can use the @not_supported_on@ guard: |
|
| 100 | 1 | ||
| 101 | 1 | ||
| 102 | 1 | not_supported_on :rubinius do |
|
| 103 | 1 | it "does some crazy stuff that rubinius people seem to hate" do |
|
| 104 | 1 | end |
|
| 105 | 1 | end |
|
| 106 | 1 | ||
| 107 | 1 | ||
| 108 | 1 | Please note that this guard should only be used when you're almost certain that a feature won't be supported in a Ruby implementation. If you intend to guard a certain case while the implementation supports it you're better off using the MSpec tagging mechanism. |
|
| 109 | 1 | ||
| 110 | 1 | If the implementation you're specifying differs from MRI you should use the @non_compliant_on@ guard. |
|
| 111 | 1 | ||
| 112 | 1 | h3. conflicts_with |
|
| 113 | 1 | ||
| 114 | 1 | If you want to make sure that another class or module is not defined in the current scope before running some tests you can use the @conflicts_with@ guard: |
|
| 115 | 1 | ||
| 116 | 1 | ||
| 117 | 1 | conflicts_with :SomeWeirdClass do |
|
| 118 | 1 | it "will not be run if SomeWeirdClass is defined" do |
|
| 119 | 1 | ... |
|
| 120 | 1 | end |
|
| 121 | 1 | end |
|
| 122 | 1 | ||
| 123 | 1 | ||
| 124 | 1 | In this case the spec will run only if SomeWeirdClass is not currently defined. It won't run if SomeWeirdClass is part of the Core classes, if it was required/included or if it was defined earlier. |
|
| 125 | 1 | ||
| 126 | 1 | h3. extended_on |
|
| 127 | 1 | ||
| 128 | 1 | ||
| 129 | 1 | h3. runner_is/runner_is_not |
|
| 130 | 1 | ||
| 131 | 1 | In some cases you might want to make sure that a set of specs runs only under a certain runner (rSpec or MSpec). You can use the @runner_is@/@runner_is_not@ guards to check this: |
|
| 132 | 1 | ||
| 133 | 1 | ||
| 134 | 1 | runner_is :rspec do |
|
| 135 | 1 | it "does something that only runs under rSpec" do |
|
| 136 | 1 | ... |
|
| 137 | 1 | end |
|
| 138 | 1 | end |
|
| 139 | 1 | ||
| 140 | 1 | runner_is :mspec do |
|
| 141 | 1 | it "does something that only runs under MSpec" do |
|
| 142 | 1 | ... |
|
| 143 | 1 | end |
|
| 144 | 1 | end |
|
| 145 | 1 | ||
| 146 | 1 | ||
| 147 | 1 | h3. quarantine! |
|
| 148 | 1 | ||
| 149 | 1 | This guard will always return false, which means that the cases inside it will *never* be run. There are only a handful of acceptable uses for this guard, so please make sure to check on IRC before using it: |
|
| 150 | 1 | ||
| 151 | 1 | ||
| 152 | 1 | quarantine! do |
|
| 153 | 1 | it "will never be run" do |
|
| 154 | 1 | ... |
|
| 155 | 1 | end |
|
| 156 | 1 | end |
|
| 157 | 1 |
