jackbox 0.9.6.2 → 0.9.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +13 -5
- data/CHANGES.txt +41 -1
- data/LICENSE.lic +0 -0
- data/README.md +244 -149
- data/Rakefile +6 -6
- data/jackbox.gemspec +3 -2
- data/lib/jackbox.rb +1 -1
- data/lib/jackbox/injectors.rb +1 -1
- data/lib/jackbox/rake.rb +1 -1
- data/lib/jackbox/tools/prefs.rb +1 -1
- data/lib/jackbox/version.rb +1 -1
- data/spec/lib/abtract_spec.rb +6 -6
- data/spec/lib/jackbox/injector_composition_spec.rb +106 -88
- data/spec/lib/jackbox/injector_directives_spec.rb +46 -0
- data/spec/lib/jackbox/injector_inheritance_spec.rb +980 -410
- data/spec/lib/jackbox/injector_introspection_spec.rb +333 -208
- data/spec/lib/jackbox/injector_spec.rb +28 -28
- data/spec/lib/jackbox/injector_versioning_spec.rb +1 -0
- data/spec/lib/jackbox/patterns_spec.rb +146 -14
- data/spec/lib/jackbox/reclassing_spec.rb +165 -78
- data/spec/lib/jackbox/vmc_spec.rb +246 -0
- metadata +32 -28
| @@ -7,16 +7,16 @@ describe "the introspection api in further detail" do | |
| 7 7 |  | 
| 8 8 | 
             
            	describe :injectors do
         | 
| 9 9 |  | 
| 10 | 
            -
            	  # . Name.injectors == [j,......]
         | 
| 11 | 
            -
            	  # . Name.injectors.by_name == [:name, ......]
         | 
| 12 | 
            -
            	  # . Name.injectors.sym_list == [:name, ......]
         | 
| 13 | 
            -
            	  # . Name.injectors.collect_by_name(:name) == [j,......]  (default method)
         | 
| 14 | 
            -
            	  #   . same as Name.injectors :name
         | 
| 15 | 
            -
            	  # . Name.injectors.all_by_sym(:name) == [j,......]  (default method)
         | 
| 16 | 
            -
            	  # . Name.injectors.find_by_name(:name) == j
         | 
| 17 | 
            -
            	  # . Name.injectors.#Enumerable...
         | 
| 18 | 
            -
                
         | 
| 19 10 | 
             
            		describe "base injectors call" do
         | 
| 11 | 
            +
                
         | 
| 12 | 
            +
            		  # . Name.injectors == [j,......]
         | 
| 13 | 
            +
            		  # . Name.injectors.by_name == [:name, ......]
         | 
| 14 | 
            +
            		  # . Name.injectors.sym_list == [:name, ......]
         | 
| 15 | 
            +
            		  # . Name.injectors.collect_by_name(:name) == [j,......]  (default method)
         | 
| 16 | 
            +
            		  #   . same as Name.injectors :name
         | 
| 17 | 
            +
            		  # . Name.injectors.all_by_sym(:name) == [j,......]  (default method)
         | 
| 18 | 
            +
            		  # . Name.injectors.find_by_name(:name) == j
         | 
| 19 | 
            +
            		  # . Name.injectors.#Enumerable...
         | 
| 20 20 |  | 
| 21 21 | 
             
            			before do
         | 
| 22 22 | 
             
            				class InjectorContainer
         | 
| @@ -47,13 +47,6 @@ describe "the introspection api in further detail" do | |
| 47 47 |  | 
| 48 48 | 
             
            			  # . Name.injectors.by_name == [:name, ......]
         | 
| 49 49 |  | 
| 50 | 
            -
            				# class InjectorContainer
         | 
| 51 | 
            -
            				# 	injector :function
         | 
| 52 | 
            -
            				# 	injector :style
         | 
| 53 | 
            -
            				# 
         | 
| 54 | 
            -
            				# 	inject function, style
         | 
| 55 | 
            -
            				# end
         | 
| 56 | 
            -
            	
         | 
| 57 50 | 
             
            				expect(InjectorContainer.injectors.by_name).to all( be_an(Symbol))
         | 
| 58 51 | 
             
            				expect(InjectorContainer.injectors.by_name).to eql([:function, :style])
         | 
| 59 52 | 
             
            				# alias
         | 
| @@ -63,16 +56,11 @@ describe "the introspection api in further detail" do | |
| 63 56 |  | 
| 64 57 | 
             
            			the 'injectors.collect_by_name returns a list of injector objects matching the name' do
         | 
| 65 58 |  | 
| 66 | 
            -
             | 
| 67 | 
            -
            				# 	injector :function
         | 
| 68 | 
            -
            				# 	injector :style
         | 
| 69 | 
            -
            				# 
         | 
| 70 | 
            -
            				# 	inject function, style
         | 
| 71 | 
            -
            				# end
         | 
| 59 | 
            +
            			  # . Name.injectors.collect_by_name(:name) == [j,......]  (default method)
         | 
| 72 60 |  | 
| 73 61 | 
             
            				ic = InjectorContainer.new
         | 
| 74 62 | 
             
            				ic.enrich InjectorContainer.style
         | 
| 75 | 
            -
            				ic.injectors.by_name.should == [: | 
| 63 | 
            +
            				ic.injectors.by_name.should == [:style, :function, :style]
         | 
| 76 64 |  | 
| 77 65 | 
             
            				# returns [Injector.name == :style, Injector.name == :style] only !!
         | 
| 78 66 | 
             
            				ic.injectors.collect_by_name(:style).should all(be_an(Injector).and have_attributes(:name => :style))
         | 
| @@ -83,18 +71,13 @@ describe "the introspection api in further detail" do | |
| 83 71 |  | 
| 84 72 | 
             
            			the 'injectors.find_by_name call returns one item of class Injector by name <sym>' do
         | 
| 85 73 |  | 
| 86 | 
            -
             | 
| 87 | 
            -
            				# 	injector :function
         | 
| 88 | 
            -
            				# 	injector :style
         | 
| 89 | 
            -
            				# 
         | 
| 90 | 
            -
            				# 	inject function, style
         | 
| 91 | 
            -
            				# end
         | 
| 74 | 
            +
            			  # . Name.injectors.find_by_name(:name) == j
         | 
| 92 75 |  | 
| 93 76 | 
             
            				ic = InjectorContainer.new
         | 
| 94 77 | 
             
            				ic.enrich InjectorContainer.style
         | 
| 95 78 |  | 
| 96 79 | 
             
            				# result
         | 
| 97 | 
            -
            				ic.injectors.by_name.should == [: | 
| 80 | 
            +
            				ic.injectors.by_name.should == [:style, :function, :style]
         | 
| 98 81 | 
             
            				ic.injectors.find_by_name(:style).should be_an(Injector).and( have_attributes(:name => :style))  # the last one !!!
         | 
| 99 82 |  | 
| 100 83 | 
             
            				# also aliased
         | 
| @@ -104,12 +87,7 @@ describe "the introspection api in further detail" do | |
| 104 87 |  | 
| 105 88 | 
             
            			the 'default calls injectors :name/injectors :name, :othername, ... get resolved to the previous methods' do
         | 
| 106 89 |  | 
| 107 | 
            -
             | 
| 108 | 
            -
            				# 	injector :function
         | 
| 109 | 
            -
            				# 	injector :style
         | 
| 110 | 
            -
            				# 
         | 
| 111 | 
            -
            				# 	inject function, style
         | 
| 112 | 
            -
            				# end
         | 
| 90 | 
            +
            			  # . Name.injectors.#Enumerable...
         | 
| 113 91 |  | 
| 114 92 | 
             
            				ic = InjectorContainer.new
         | 
| 115 93 | 
             
            				ic.enrich InjectorContainer.style
         | 
| @@ -122,151 +100,185 @@ describe "the introspection api in further detail" do | |
| 122 100 |  | 
| 123 101 | 
             
            		end
         | 
| 124 102 |  | 
| 125 | 
            -
            		describe '#injectors at the class singleton level' do
         | 
| 126 | 
            -
             | 
| 127 | 
            -
            			the 'injectors applied at the class INSTANCE level show only on the class not the object instances' do
         | 
| 128 103 |  | 
| 129 | 
            -
             | 
| 130 | 
            -
            					def new *args
         | 
| 131 | 
            -
            						puts "--done--"
         | 
| 132 | 
            -
            						super(*args)
         | 
| 133 | 
            -
            					end
         | 
| 134 | 
            -
            				end
         | 
| 135 | 
            -
             | 
| 136 | 
            -
            				class InjectorUser
         | 
| 137 | 
            -
            					# ...
         | 
| 138 | 
            -
            				end
         | 
| 139 | 
            -
             | 
| 140 | 
            -
            				InjectorUser.extend class_injector
         | 
| 141 | 
            -
             | 
| 142 | 
            -
            				$stdout.should_receive(:puts).with("--done--")
         | 
| 143 | 
            -
            				iu = InjectorUser.new
         | 
| 144 | 
            -
             | 
| 145 | 
            -
            				InjectorUser.injectors.size.should == 1
         | 
| 146 | 
            -
            				InjectorUser.injectors.should all(be_an(Injector).and have_attributes(:name => :class_injector))
         | 
| 147 | 
            -
             | 
| 148 | 
            -
            				if iu.respond_to? :injectors								# done to run this file independent of the others
         | 
| 149 | 
            -
            					iu.injectors.should be_empty
         | 
| 150 | 
            -
            				else
         | 
| 151 | 
            -
            					expect{
         | 
| 152 | 
            -
            						iu.injectors
         | 
| 153 | 
            -
            					}.to raise_error(NoMethodError)
         | 
| 154 | 
            -
            				end
         | 
| 104 | 
            +
            		describe "#injectors(:all) call" do
         | 
| 155 105 |  | 
| 106 | 
            +
            			before do
         | 
| 107 | 
            +
            				injector :Example1
         | 
| 108 | 
            +
            				injector :Example2
         | 
| 109 | 
            +
            				Object.inject Example1()
         | 
| 156 110 | 
             
            			end
         | 
| 157 | 
            -
             | 
| 158 | 
            -
            			 | 
| 159 | 
            -
             | 
| 160 | 
            -
            				 | 
| 161 | 
            -
            				injector :one
         | 
| 162 | 
            -
             | 
| 163 | 
            -
            				Array.inject two 														# injected on objects of the class
         | 
| 164 | 
            -
            				Array.extend one														# extended on the class instance itself
         | 
| 165 | 
            -
             | 
| 166 | 
            -
            				# result
         | 
| 167 | 
            -
             | 
| 168 | 
            -
            				Array.injectors.sym_list.should == [:one, :two]
         | 
| 169 | 
            -
             | 
| 111 | 
            +
            			
         | 
| 112 | 
            +
            			after do
         | 
| 113 | 
            +
            				Example1(:implode)
         | 
| 114 | 
            +
            				Example2(:implode)
         | 
| 170 115 | 
             
            			end
         | 
| 171 116 |  | 
| 172 | 
            -
            		end
         | 
| 173 | 
            -
             | 
| 174 | 
            -
            		describe "#injectors(:all) call" do
         | 
| 175 | 
            -
             | 
| 176 | 
            -
            			injector :Example1
         | 
| 177 | 
            -
            			injector :Example2
         | 
| 178 | 
            -
             | 
| 179 117 | 
             
            			it 'returns all the injectors in the ancestor chain of an object' do
         | 
| 180 118 |  | 
| 181 | 
            -
            				Object.eject *Object.injectors rescue []  # clear all injectors from other tests
         | 
| 119 | 
            +
            				# Object.eject *Object.injectors rescue []  # clear all injectors from other tests
         | 
| 182 120 |  | 
| 183 | 
            -
            				Object.inject Example1()
         | 
| 184 121 | 
             
            				Hash.inject Example2()
         | 
| 185 122 |  | 
| 186 123 | 
             
            				Hash.new.injectors(:all).should all(be_an(Injector))
         | 
| 187 | 
            -
            				Hash.new.injectors(:all). | 
| 124 | 
            +
            				Hash.new.injectors(:all).should eql [Example2(), Example1()]  # from Object, and Hash
         | 
| 188 125 |  | 
| 189 126 | 
             
            				# as opposed to simple #injectors call
         | 
| 190 | 
            -
            				 | 
| 127 | 
            +
            				
         | 
| 128 | 
            +
            				Hash.new.injectors.should eql [Example2()] # with no :all option
         | 
| 191 129 |  | 
| 192 130 | 
             
            			end
         | 
| 193 131 |  | 
| 194 | 
            -
            			it ' | 
| 132 | 
            +
            			it 'with any class' do
         | 
| 195 133 |  | 
| 196 134 | 
             
            				# Object.eject *Object.injectors          	# clear all injectors from other tests
         | 
| 197 135 |  | 
| 198 | 
            -
            				class  | 
| 136 | 
            +
            				class AnyClass
         | 
| 199 137 | 
             
            					inject Example2()
         | 
| 200 138 | 
             
            				end
         | 
| 201 139 |  | 
| 202 | 
            -
            				 | 
| 203 | 
            -
            				 | 
| 140 | 
            +
            				AnyClass.injectors(:all).should all(be_an(Injector))
         | 
| 141 | 
            +
            				AnyClass.injectors(:all).should eql [Example2(), Example1()]
         | 
| 204 142 |  | 
| 205 143 | 
             
            				# as opposed to simple #injectors call
         | 
| 206 | 
            -
            				 | 
| 144 | 
            +
            				
         | 
| 145 | 
            +
            				AnyClass.new.injectors.should eql [Example2()]
         | 
| 207 146 |  | 
| 208 147 | 
             
            			end
         | 
| 209 148 |  | 
| 210 149 | 
             
            			it 'returns all the injectors in the ancestors chain of a module' do
         | 
| 211 150 |  | 
| 212 | 
            -
            				module  | 
| 151 | 
            +
            				module AnyModule
         | 
| 152 | 
            +
            					
         | 
| 213 153 | 
             
            					inject Example2() do
         | 
| 214 | 
            -
            						include injector : | 
| 154 | 
            +
            						include injector :Example3  		# compond injector
         | 
| 215 155 | 
             
            					end
         | 
| 156 | 
            +
            					
         | 
| 216 157 | 
             
            				end
         | 
| 217 158 |  | 
| 218 | 
            -
            				 | 
| 219 | 
            -
            				 | 
| 220 | 
            -
             | 
| 159 | 
            +
            				AnyModule.injectors(:all).should all(be_an(Injector))
         | 
| 160 | 
            +
            				AnyModule.injectors(:all).should eql [Example2(), Example3()]
         | 
| 161 | 
            +
            				
         | 
| 221 162 | 
             
            				# as opposed to simple #injectors call
         | 
| 222 | 
            -
            				 | 
| 163 | 
            +
            				
         | 
| 164 | 
            +
            				AnyModule.injectors.should eql [Example2()]
         | 
| 223 165 |  | 
| 224 166 | 
             
            			end
         | 
| 225 167 |  | 
| 226 168 | 
             
            			it 'returns all the injectors in the ancestors chain of a Injector' do
         | 
| 227 169 |  | 
| 228 | 
            -
            				 | 
| 170 | 
            +
            				Example1 do
         | 
| 171 | 
            +
            					
         | 
| 229 172 | 
             
            					include injector :Example2 do
         | 
| 230 | 
            -
            						include injector : | 
| 173 | 
            +
            						include injector :Example3					# triple compound injector
         | 
| 231 174 | 
             
            					end
         | 
| 175 | 
            +
            					
         | 
| 232 176 | 
             
            				end
         | 
| 233 177 |  | 
| 234 178 | 
             
            				Example1().injectors(:all).should all(be_an(Injector)) 
         | 
| 235 | 
            -
            				Example1().injectors(:all). | 
| 179 | 
            +
            				Example1().injectors(:all).should eql [Example2(), Example3()]
         | 
| 236 180 |  | 
| 237 181 | 
             
            				# as opposed to simple #injectors call
         | 
| 238 | 
            -
            				 | 
| 182 | 
            +
            				
         | 
| 183 | 
            +
            				Example1().injectors.should eql [Example2()]
         | 
| 239 184 |  | 
| 240 185 | 
             
            			end
         | 
| 241 186 |  | 
| 242 187 | 
             
            			it 'allows the rest of the api on the entire list' do
         | 
| 243 188 |  | 
| 244 | 
            -
            				Example1 | 
| 245 | 
            -
             | 
| 246 | 
            -
             | 
| 189 | 
            +
            				Example1 do
         | 
| 190 | 
            +
            					
         | 
| 191 | 
            +
            					include injector :Example2 do
         | 
| 192 | 
            +
            						include injector :Example3					# triple compound injector
         | 
| 193 | 
            +
            					end
         | 
| 194 | 
            +
            					
         | 
| 195 | 
            +
            				end
         | 
| 196 | 
            +
             | 
| 197 | 
            +
            				Example1().injectors(:all).by_name.should == [:Example2, :Example3] 
         | 
| 198 | 
            +
            				Example1().injectors(:all).collect_by_name(:Example3).should all(be_an(Injector).and have_attributes(:name => :Example3))
         | 
| 199 | 
            +
            				Example1().injectors(:all).find_by_name(:Example2).should == Example2()
         | 
| 247 200 |  | 
| 248 201 | 
             
            			end
         | 
| 249 202 | 
             
            		end
         | 
| 250 203 |  | 
| 204 | 
            +
             | 
| 205 | 
            +
            		describe '#injectors at the class singleton level' do
         | 
| 206 | 
            +
             | 
| 207 | 
            +
            			the 'injectors applied at the CLASS instance level, ie: using extend on the class, show up only on the CLASS instance not 
         | 
| 208 | 
            +
            			its object instances and this only after using the :all directive like above' do
         | 
| 209 | 
            +
             | 
| 210 | 
            +
            				injector :class_Instance_injector do
         | 
| 211 | 
            +
            					def new *args
         | 
| 212 | 
            +
            						puts "--done--"
         | 
| 213 | 
            +
            						super(*args)
         | 
| 214 | 
            +
            					end
         | 
| 215 | 
            +
            				end
         | 
| 216 | 
            +
             | 
| 217 | 
            +
            				class InjectorUser
         | 
| 218 | 
            +
            					# ...
         | 
| 219 | 
            +
            				end
         | 
| 220 | 
            +
             | 
| 221 | 
            +
            				# extend the class singleton
         | 
| 222 | 
            +
             | 
| 223 | 
            +
            				InjectorUser.extend class_Instance_injector					
         | 
| 224 | 
            +
             | 
| 225 | 
            +
            				# run tests
         | 
| 226 | 
            +
             | 
| 227 | 
            +
            				InjectorUser.injectors.size.should == 0		# not using the :all directive
         | 
| 228 | 
            +
             | 
| 229 | 
            +
            				InjectorUser.injectors(:all).size.should == 1
         | 
| 230 | 
            +
            				InjectorUser.injectors(:all).should all(be_an(Injector).and have_attributes(:name => :class_Instance_injector))
         | 
| 231 | 
            +
             | 
| 232 | 
            +
            				# on the class instance
         | 
| 233 | 
            +
             | 
| 234 | 
            +
            				$stdout.should_receive(:puts).with("--done--")
         | 
| 235 | 
            +
            				
         | 
| 236 | 
            +
            				iu = InjectorUser.new
         | 
| 237 | 
            +
            				expect(iu.injectors).to be_empty
         | 
| 238 | 
            +
            				expect(iu.injectors(:all)).to be_empty
         | 
| 239 | 
            +
             | 
| 240 | 
            +
            			end
         | 
| 241 | 
            +
             | 
| 242 | 
            +
            			the ':all injector list for classes lists CLASS instance injectors first and then OBJECT instance injectors' do
         | 
| 243 | 
            +
             | 
| 244 | 
            +
            				injector :two
         | 
| 245 | 
            +
            				injector :one
         | 
| 246 | 
            +
             | 
| 247 | 
            +
            				Array.inject two 														# injected on objects of the class
         | 
| 248 | 
            +
            				Array.extend one														# extended on the class instance itself
         | 
| 249 | 
            +
             | 
| 250 | 
            +
            				# result
         | 
| 251 | 
            +
             | 
| 252 | 
            +
            				Array.injectors(:all).sym_list.should == [:one, :two]
         | 
| 253 | 
            +
            				
         | 
| 254 | 
            +
            				Array.new.injectors.sym_list.should == [:two] 	# :one is member of Array.singleton_class 
         | 
| 255 | 
            +
            																												# and does not become part of Array.instances
         | 
| 256 | 
            +
            			end
         | 
| 257 | 
            +
             | 
| 258 | 
            +
            		end
         | 
| 251 259 | 
             
            	end
         | 
| 252 260 |  | 
| 261 | 
            +
             | 
| 253 262 | 
             
            	describe :history do
         | 
| 254 263 |  | 
| 255 | 
            -
            		 | 
| 264 | 
            +
            		
         | 
| 265 | 
            +
            		jack :Histample
         | 
| 266 | 
            +
            		             
         | 
| 256 267 |  | 
| 257 268 | 
             
            		it 'does not show original jack' do 
         | 
| 258 269 | 
             
            			expect(Histample().history.first).to eq(nil)
         | 
| 259 270 | 
             
            		end 
         | 
| 260 271 |  | 
| 261 | 
            -
            		it "shows additional jacks after  | 
| 272 | 
            +
            		it "shows additional jacks once hosted, i.e.: after extend/include" do
         | 
| 262 273 |  | 
| 263 | 
            -
            			extend(Histample(), Histample())
         | 
| 274 | 
            +
            			extend(Histample(), Histample())					# host two items
         | 
| 264 275 |  | 
| 265 | 
            -
            			injectors.should == Histample().history
         | 
| 276 | 
            +
            			injectors.should == Histample().history		# equal at this point
         | 
| 266 277 |  | 
| 267 278 | 
             
            			expect(Histample().history.size).to eq(2)
         | 
| 268 | 
            -
            			expect(Histample().history.last).to eql( | 
| 269 | 
            -
            			expect(Histample().history. | 
| 279 | 
            +
            			expect(Histample().history.last).to eql(injectors.last)
         | 
| 280 | 
            +
            			expect(Histample().history.first).to eq(injectors.first)
         | 
| 281 | 
            +
            			expect(injectors.size).to eq(2)
         | 
| 270 282 |  | 
| 271 283 | 
             
            			eject *injectors
         | 
| 272 284 |  | 
| @@ -280,13 +292,6 @@ describe "the introspection api in further detail" do | |
| 280 292 |  | 
| 281 293 | 
             
            			expect(Histample().history.slice(0)).to be_instance_of(Injector)
         | 
| 282 294 | 
             
            			expect(Histample().history.slice(1)).to be_instance_of(Injector) 
         | 
| 283 | 
            -
            			expect(Histample().history.slice(0)).to eq(Histample())
         | 
| 284 | 
            -
            			expect(Histample().history.slice(1)).to eq(Histample()) 
         | 
| 285 | 
            -
            			
         | 
| 286 | 
            -
            			# values are different than spec
         | 
| 287 | 
            -
            			
         | 
| 288 | 
            -
            			expect(Histample().history.slice(0)).not_to eq(Histample().spec)
         | 
| 289 | 
            -
            			expect(Histample().history.slice(1)).not_to eq(Histample().spec) 
         | 
| 290 295 |  | 
| 291 296 | 
             
            			eject Histample(), Histample()
         | 
| 292 297 |  | 
| @@ -296,37 +301,33 @@ describe "the introspection api in further detail" do | |
| 296 301 |  | 
| 297 302 | 
             
            			extend(Histample(), Histample())
         | 
| 298 303 |  | 
| 304 | 
            +
            			injectors.should == Histample().history
         | 
| 305 | 
            +
             | 
| 299 306 | 
             
            			expect(Histample().history.size).to eq(2)
         | 
| 300 | 
            -
            			expect( | 
| 301 | 
            -
            			expect(Histample().history.last).to_not eq(Histample().spec)
         | 
| 307 | 
            +
            			expect(injectors.size).to eq(2)
         | 
| 302 308 |  | 
| 303 309 | 
             
            			eject *injectors
         | 
| 304 310 |  | 
| 305 311 | 
             
            			expect(injectors).to be_empty  							# target injectors
         | 
| 306 | 
            -
            			
         | 
| 307 | 
            -
            			expect(Histample().history.size).to eq(0)    # Injector history
         | 
| 308 | 
            -
            			expect(Histample().history.first).to eq(nil)
         | 
| 309 | 
            -
            			expect(Histample().history.last).to eq(nil)
         | 
| 312 | 
            +
            			expect(Histample().history).to be_empty			# Injector history
         | 
| 310 313 |  | 
| 311 314 | 
             
            		end
         | 
| 312 315 |  | 
| 313 | 
            -
            		it 'swallows un-hosted elements other than original' do
         | 
| 316 | 
            +
            		it 'swallows un-hosted elements other than original one' do
         | 
| 314 317 |  | 
| 315 318 | 
             
            			Histample() #un-hosted Histample 
         | 
| 316 319 | 
             
            			Histample() #un-hosted Histample
         | 
| 317 320 |  | 
| 318 | 
            -
            			expect(Histample().history.first).to eq(nil)
         | 
| 319 321 | 
             
            			expect(Histample().history.size).to eq(0)
         | 
| 320 | 
            -
            			expect(Histample().history.last).to eq(nil)
         | 
| 321 322 |  | 
| 322 323 | 
             
            		end
         | 
| 323 324 |  | 
| 324 | 
            -
            		it 'shows  | 
| 325 | 
            +
            		it 'shows hosted items upon inspection' do
         | 
| 325 326 |  | 
| 326 327 | 
             
            			extend Histample()
         | 
| 327 328 |  | 
| 329 | 
            +
            			expect(Histample().history.inspect).to match(/\[\(\|Histample\|.+\)\]/)
         | 
| 328 330 | 
             
            			expect(Histample().history.size).to eq(1)
         | 
| 329 | 
            -
            			expect(Histample().history.inspect).to match(/\[\(.+\|Histample\|\)\]/)
         | 
| 330 331 |  | 
| 331 332 | 
             
            			eject Histample()
         | 
| 332 333 |  | 
| @@ -337,26 +338,46 @@ describe "the introspection api in further detail" do | |
| 337 338 | 
             
            			it 'points to the previous injector in the history' do
         | 
| 338 339 |  | 
| 339 340 | 
             
            				extend Histample(), Histample()
         | 
| 340 | 
            -
             | 
| 341 | 
            +
            				
         | 
| 342 | 
            +
            				# Given that
         | 
| 341 343 | 
             
            				injectors.should == Histample().history
         | 
| 342 344 |  | 
| 345 | 
            +
            				# Then 
         | 
| 343 346 | 
             
            				expect(Histample().history.last.precedent).to equal(Histample().history.first)
         | 
| 344 347 | 
             
            				expect(Histample().history.last.pre).to equal(injectors.first)
         | 
| 345 348 | 
             
            				expect(injectors.last.precedent).to equal(Histample().history.first)
         | 
| 346 349 | 
             
            				expect(injectors.last.pre).to equal(injectors.first)
         | 
| 350 | 
            +
            				
         | 
| 351 | 
            +
            				eject *injectors
         | 
| 352 | 
            +
            				
         | 
| 353 | 
            +
            			end
         | 
| 354 | 
            +
            			
         | 
| 355 | 
            +
            			it 'has spec as the first precedent' do
         | 
| 356 | 
            +
            				
         | 
| 357 | 
            +
            				extend Histample(), Histample()
         | 
| 358 | 
            +
            				
         | 
| 359 | 
            +
            				injectors.should == Histample().history
         | 
| 360 | 
            +
            				
         | 
| 347 361 | 
             
            				expect(Histample().history.first.precedent).to equal(Histample().spec)
         | 
| 348 362 | 
             
            				expect(injectors.first.precedent).to equal(Histample().spec)
         | 
| 349 | 
            -
            				expect(Histample().spec.pre).to eq(nil) 
         | 
| 350 363 |  | 
| 351 364 | 
             
            				eject *injectors
         | 
| 352 365 |  | 
| 353 366 | 
             
            			end
         | 
| 367 | 
            +
            			
         | 
| 368 | 
            +
            			# but then... aka: its a circular list
         | 
| 354 369 |  | 
| 355 | 
            -
            			it 'has  | 
| 356 | 
            -
             | 
| 357 | 
            -
            				 | 
| 358 | 
            -
            				 | 
| 359 | 
            -
            				 | 
| 370 | 
            +
            			it 'has the latest version as the precedent to spec' do
         | 
| 371 | 
            +
            				
         | 
| 372 | 
            +
            				extend Histample(), Histample()
         | 
| 373 | 
            +
            				
         | 
| 374 | 
            +
            				injectors.should == Histample().history
         | 
| 375 | 
            +
            				
         | 
| 376 | 
            +
            				expect(Histample().history.first.precedent).to equal(Histample().spec)
         | 
| 377 | 
            +
            				expect(Histample().precedent.pre.pre).to equal(Histample().spec)
         | 
| 378 | 
            +
            				expect(Histample().spec.pre).to eq(Histample().history.last) 
         | 
| 379 | 
            +
            				
         | 
| 380 | 
            +
            				eject *injectors
         | 
| 360 381 |  | 
| 361 382 | 
             
            			end
         | 
| 362 383 |  | 
| @@ -377,65 +398,80 @@ describe "the introspection api in further detail" do | |
| 377 398 | 
             
            			expect(Progample().history).to be_empty
         | 
| 378 399 | 
             
            			expect(Progample().progenitor).to equal(Progample().spec)
         | 
| 379 400 |  | 
| 401 | 
            +
            			# apply the injector
         | 
| 402 | 
            +
            			
         | 
| 380 403 | 
             
            			extend Progample(), Progample()       
         | 
| 381 404 |  | 
| 382 405 | 
             
            			expect(Progample().history.size).to eq(2)
         | 
| 406 | 
            +
            			
         | 
| 407 | 
            +
            			
         | 
| 408 | 
            +
            			# both generated form spec
         | 
| 409 | 
            +
            			
         | 
| 383 410 | 
             
            			expect(Progample().history.first.progenitor).to equal(Progample().spec)
         | 
| 384 411 | 
             
            			expect(Progample().history.last.progenitor).to equal(Progample().spec)
         | 
| 385 412 |  | 
| 386 | 
            -
             | 
| 413 | 
            +
             | 
| 414 | 
            +
            			# create a tag
         | 
| 415 | 
            +
            			
         | 
| 416 | 
            +
            			suppress_warnings do # used because of rspec
         | 
| 387 417 | 
             
            				ProgenitorsTag = Progample()
         | 
| 388 418 | 
             
            			end
         | 
| 389 419 |  | 
| 390 420 | 
             
            			expect(Progample().history.size).to eq(3)
         | 
| 421 | 
            +
            			
         | 
| 391 422 | 
             
            			expect(Progample().history.first.progenitor).to equal(Progample().spec)
         | 
| 392 | 
            -
            			expect(Progample().history. | 
| 423 | 
            +
            			expect(Progample().history.last).to equal(ProgenitorsTag)
         | 
| 393 424 | 
             
            			expect(Progample().history.last.progenitor).to equal(Progample().spec)
         | 
| 425 | 
            +
            			expect(ProgenitorsTag.progenitor).to equal(Progample().spec)
         | 
| 394 426 |  | 
| 427 | 
            +
             | 
| 428 | 
            +
            			# apply the tag
         | 
| 429 | 
            +
            			
         | 
| 395 430 | 
             
            			extend ProgenitorsTag
         | 
| 396 431 |  | 
| 397 432 | 
             
            			expect(Progample().history.size).to eq(4)
         | 
| 398 | 
            -
            			expect(Progample().history.last).to equal(injectors. | 
| 433 | 
            +
            			expect(Progample().history.last).to equal(injectors.first)
         | 
| 399 434 |  | 
| 400 435 | 
             
            			expect(Progample().history.last.progenitor).to equal(ProgenitorsTag) 
         | 
| 401 | 
            -
            			expect(Progample().history.last.progenitor).to equal(Progample().history.slice(2)) 
         | 
| 402 | 
            -
            			expect(Progample().history.slice(2).progenitor).to equal(Progample().spec)
         | 
| 403 | 
            -
            			expect(Progample().history.slice(1).progenitor).to equal(Progample().spec)
         | 
| 404 436 | 
             
            			expect(Progample().history.first.progenitor).to equal(Progample().spec)
         | 
| 405 | 
            -
            			expect(Progample().spec.progenitor).to equal(nil)
         | 
| 406 | 
            -
            			expect(ProgenitorsTag.progenitor).to equal(Progample().spec)
         | 
| 407 | 
            -
            			expect(ProgenitorsTag.progenitor.progenitor).to equal(nil)
         | 
| 408 437 |  | 
| 409 | 
            -
             | 
| 438 | 
            +
            		end
         | 
| 439 | 
            +
            		
         | 
| 440 | 
            +
            		it 'points the last progenitor to nil' do
         | 
| 441 | 
            +
            			
         | 
| 442 | 
            +
            			expect(Progample().spec.progenitor).to equal(nil)
         | 
| 410 443 |  | 
| 411 444 | 
             
            		end
         | 
| 412 445 |  | 
| 413 | 
            -
            		it ' | 
| 446 | 
            +
            		it 'works the same with soft tags' do
         | 
| 414 447 |  | 
| 415 448 | 
             
            			suppress_warnings do
         | 
| 416 449 | 
             
            				ProgenitorsTag = Progample()
         | 
| 417 450 | 
             
            			end
         | 
| 418 451 |  | 
| 419 452 | 
             
            			expect(Progample().history.size).to eq(1)
         | 
| 420 | 
            -
            			expect(Progample().history.slice(0)).to equal(ProgenitorsTag)
         | 
| 421 453 |  | 
| 422 | 
            -
             | 
| 454 | 
            +
             | 
| 455 | 
            +
            			# soft tag
         | 
| 456 | 
            +
            			# debugger
         | 
| 457 | 
            +
            			Progample(:tag) { 'some code'}       			
         | 
| 423 458 |  | 
| 424 459 | 
             
            			expect(Progample().history.size).to eq(2)
         | 
| 425 | 
            -
             | 
| 426 | 
            -
            			 | 
| 460 | 
            +
             | 
| 461 | 
            +
            			# progenitors are the same
         | 
| 462 | 
            +
            			
         | 
| 427 463 | 
             
            			expect(Progample().history.first.progenitor).to eq(Progample().spec)
         | 
| 428 464 | 
             
            			expect(Progample().history.last.progenitor).to eq(Progample().spec)
         | 
| 429 465 | 
             
            			expect(Progample().history.first.progenitor.progenitor).to eq(nil)
         | 
| 430 466 | 
             
            			expect(Progample().history.last.progenitor.progenitor).to eq(nil)
         | 
| 431 | 
            -
            			expect(ProgenitorsTag.progenitor).to equal(Progample().spec)
         | 
| 432 | 
            -
            			expect(ProgenitorsTag.progenitor.progenitor).to equal(nil)
         | 
| 433 467 |  | 
| 468 | 
            +
            			# tags call
         | 
| 469 | 
            +
            			
         | 
| 434 470 | 
             
            			expect(Progample().tags.size).to eq(2)
         | 
| 435 471 |  | 
| 436 472 | 
             
            		end
         | 
| 437 473 |  | 
| 438 | 
            -
            		it ' | 
| 474 | 
            +
            		it 'carries on the metaphor with injectors are shared from other objects' do
         | 
| 439 475 |  | 
| 440 476 | 
             
            			suppress_warnings do
         | 
| 441 477 | 
             
            				ProgenitorsTag = Progample()
         | 
| @@ -446,20 +482,13 @@ describe "the introspection api in further detail" do | |
| 446 482 | 
             
            			end
         | 
| 447 483 |  | 
| 448 484 | 
             
            			class ProgenitorTester2
         | 
| 449 | 
            -
            				include *ProgenitorTester1.injectors
         | 
| 485 | 
            +
            				include *ProgenitorTester1.injectors   # copying injectors from second class
         | 
| 450 486 | 
             
            			end
         | 
| 451 487 |  | 
| 452 488 | 
             
            			expect(ProgenitorTester2.injectors.first.progenitor).to equal(ProgenitorTester1.injectors.first)
         | 
| 453 489 | 
             
            			expect(ProgenitorTester1.injectors.first.progenitor).to equal(ProgenitorsTag)
         | 
| 454 490 | 
             
            			expect(ProgenitorsTag.progenitor).to equal(Progample().spec)  
         | 
| 455 491 |  | 
| 456 | 
            -
            			with ProgenitorTester1 do
         | 
| 457 | 
            -
            				eject *injectors
         | 
| 458 | 
            -
            			end
         | 
| 459 | 
            -
            			
         | 
| 460 | 
            -
            			expect(ProgenitorTester2.injectors.first.progenitor).to equal(ProgenitorsTag)
         | 
| 461 | 
            -
            			expect(ProgenitorsTag.progenitor).to equal(Progample().spec)  
         | 
| 462 | 
            -
             | 
| 463 492 | 
             
            		end
         | 
| 464 493 |  | 
| 465 494 | 
             
            	end 
         | 
| @@ -511,101 +540,197 @@ describe "the introspection api in further detail" do | |
| 511 540 | 
             
            		end
         | 
| 512 541 |  | 
| 513 542 | 
             
            		# For now this is how equality is defined
         | 
| 514 | 
            -
            		describe 'equality' do
         | 
| 543 | 
            +
            		describe 'equality and inequality' do
         | 
| 515 544 |  | 
| 516 545 | 
             
            			it 'allows comparison between injectors' do
         | 
| 517 546 |  | 
| 547 | 
            +
            				# equality
         | 
| 548 | 
            +
            				##################################
         | 
| 518 549 | 
             
            				E().should == E()
         | 
| 519 | 
            -
            				E(). | 
| 550 | 
            +
            				E().should == E().spec
         | 
| 520 551 |  | 
| 521 552 | 
             
            				E(:tag).should == E()
         | 
| 522 | 
            -
            				ETag1 = E()
         | 
| 523 | 
            -
             | 
| 524 | 
            -
            				
         | 
| 553 | 
            +
            				if ETag1 = E()
         | 
| 554 | 
            +
            					ETag1.should == E()
         | 
| 555 | 
            +
            				end
         | 
| 525 556 | 
             
            				extend E()
         | 
| 526 557 | 
             
            				injectors.first.should == E()
         | 
| 527 558 |  | 
| 559 | 
            +
            				
         | 
| 560 | 
            +
            				# ** definition **
         | 
| 528 561 | 
             
            				E() do
         | 
| 529 | 
            -
            					def foo                    | 
| 562 | 
            +
            					def foo                   
         | 
| 530 563 | 
             
            					end
         | 
| 531 564 | 
             
            				end     
         | 
| 532 | 
            -
            				
         | 
| 565 | 
            +
            				# ** definition **
         | 
| 566 | 
            +
             | 
| 567 | 
            +
             | 
| 568 | 
            +
            				# inequality
         | 
| 569 | 
            +
            				##################################
         | 
| 533 570 | 
             
            				E().should == E()
         | 
| 534 571 | 
             
            				ETag1.should_not == E()
         | 
| 535 572 | 
             
            				injectors.first.should_not == E()
         | 
| 536 | 
            -
            				E(:tag).should == E()
         | 
| 537 573 |  | 
| 574 | 
            +
            				E(:tag).should == E()
         | 
| 538 575 | 
             
            				E().should_not == F()
         | 
| 539 576 |  | 
| 540 577 | 
             
            			end
         | 
| 541 578 |  | 
| 542 579 | 
             
            		end
         | 
| 543 580 |  | 
| 544 | 
            -
            		describe  | 
| 581 | 
            +
            		describe :diff do
         | 
| 545 582 |  | 
| 546 583 | 
             
            			it 'shows the difference between injectors' do
         | 
| 547 | 
            -
             | 
| 548 | 
            -
            				E().diff. | 
| 584 | 
            +
             | 
| 585 | 
            +
            				E().diff.class.should be(Array)
         | 
| 586 | 
            +
             | 
| 587 | 
            +
            				# equality in the converse expression
         | 
| 588 | 
            +
            				##################################
         | 
| 589 | 
            +
            				# debugger
         | 
| 590 | 
            +
            				E().diff(E()).should be_empty  	
         | 
| 591 | 
            +
             | 
| 592 | 
            +
            				# because
         | 
| 593 | 
            +
            				E().should == E()               # like above
         | 
| 594 | 
            +
            				
         | 
| 595 | 
            +
            				
         | 
| 596 | 
            +
            			  # unless changed E should be == E().pre or E().spec
         | 
| 597 | 
            +
            				##################################
         | 
| 598 | 
            +
            				E().diff.should be_empty
         | 
| 599 | 
            +
             | 
| 549 600 | 
             
            				# because
         | 
| 550 | 
            -
            				E(). | 
| 601 | 
            +
            				E().diff.should == E().diff(E().pre)        
         | 
| 602 | 
            +
            				E().pre.should equal( E().spec )
         | 
| 603 | 
            +
            				# and
         | 
| 604 | 
            +
            				E().should == E().spec      # like above
         | 
| 551 605 |  | 
| 552 606 |  | 
| 607 | 
            +
            				# unless there is a delta it cannot be loaded?
         | 
| 553 608 | 
             
            				##################################
         | 
| 554 609 | 
             
            				E().diff.should_not be_loaded
         | 
| 610 | 
            +
             | 
| 555 611 | 
             
            				# because
         | 
| 556 | 
            -
            				E().diff. | 
| 557 | 
            -
            				E().diff.delta.should_not be_empty
         | 
| 558 | 
            -
            		
         | 
| 612 | 
            +
            				E().diff.delta.should be_empty
         | 
| 559 613 |  | 
| 614 | 
            +
             | 
| 615 | 
            +
            				# tags are the same
         | 
| 560 616 | 
             
            				##################################
         | 
| 561 | 
            -
            				E().diff(E()).should be_empty  	
         | 
| 562 | 
            -
            				# because
         | 
| 563 | 
            -
            				E().should == E()               # like above
         | 
| 564 | 
            -
            				
         | 
| 565 617 | 
             
            				ETag2 = E()
         | 
| 566 618 |  | 
| 567 | 
            -
            		
         | 
| 568 | 
            -
            				##################################
         | 
| 569 619 | 
             
            				E().diff(ETag2).should be_empty
         | 
| 570 620 | 
             
            				ETag2.diff(E()).should be_empty
         | 
| 621 | 
            +
             | 
| 571 622 | 
             
            				# because 
         | 
| 572 | 
            -
            				ETag2.should == E() 						 | 
| 623 | 
            +
            				ETag2.should == E() 						
         | 
| 624 | 
            +
            				E().should == ETag2 						# like above
         | 
| 573 625 |  | 
| 626 | 
            +
            			end
         | 
| 627 | 
            +
            				
         | 
| 628 | 
            +
            			it 'differs once a definition is present' do
         | 
| 629 | 
            +
            				
         | 
| 630 | 
            +
            				# a tag to compare
         | 
| 631 | 
            +
            				##################################
         | 
| 632 | 
            +
            				ETag3 = E()
         | 
| 633 | 
            +
             | 
| 634 | 
            +
             | 
| 635 | 
            +
            				# ** definition **
         | 
| 574 636 | 
             
            				E do
         | 
| 575 | 
            -
            					def foo 									 | 
| 637 | 
            +
            					def foo 									
         | 
| 576 638 | 
             
            					end
         | 
| 577 639 | 
             
            				end
         | 
| 578 | 
            -
            				
         | 
| 579 | 
            -
             | 
| 580 | 
            -
             | 
| 581 | 
            -
            				E | 
| 640 | 
            +
            				# ** definition **
         | 
| 641 | 
            +
             | 
| 642 | 
            +
             | 
| 643 | 
            +
            				# E is changed so...
         | 
| 644 | 
            +
            				####################################
         | 
| 645 | 
            +
            				E().diff(ETag3).should_not be_empty
         | 
| 646 | 
            +
             | 
| 582 647 | 
             
            				# because
         | 
| 583 | 
            -
            			   | 
| 648 | 
            +
            			  ETag3.should_not == E() 
         | 
| 649 | 
            +
            				# and
         | 
| 650 | 
            +
            				E().diff(ETag3).delta.should == [:foo]
         | 
| 584 651 |  | 
| 585 | 
            -
            				 | 
| 586 | 
            -
            				 | 
| 652 | 
            +
            				
         | 
| 653 | 
            +
            				# Still not loaded
         | 
| 654 | 
            +
            				##################################
         | 
| 655 | 
            +
            				E().diff(ETag3).should_not be_loaded
         | 
| 656 | 
            +
             | 
| 587 657 | 
             
            				# because
         | 
| 588 | 
            -
            				E().diff( | 
| 589 | 
            -
            				#  | 
| 590 | 
            -
            				E().diff( | 
| 658 | 
            +
            				E().diff(ETag3).join.should == []
         | 
| 659 | 
            +
            				# even though
         | 
| 660 | 
            +
            				E().diff(ETag3).delta.should == [:foo]
         | 
| 591 661 |  | 
| 592 | 
            -
             | 
| 662 | 
            +
             | 
| 663 | 
            +
            				# conversely
         | 
| 593 664 | 
             
            				######################################
         | 
| 594 | 
            -
            				E().diff.should be_loaded
         | 
| 595 | 
            -
            				# because 
         | 
| 596 665 | 
             
            				E().diff.join.should == [:foo]
         | 
| 597 | 
            -
            				 | 
| 598 | 
            -
            				 | 
| 599 | 
            -
             | 
| 600 | 
            -
            				#  | 
| 601 | 
            -
            				E().diff. | 
| 602 | 
            -
            				#  | 
| 603 | 
            -
            				E(). | 
| 604 | 
            -
             | 
| 666 | 
            +
            				# and
         | 
| 667 | 
            +
            				E().diff.delta.should == []
         | 
| 668 | 
            +
             | 
| 669 | 
            +
            				# because 
         | 
| 670 | 
            +
            				E().diff.should_not be_loaded
         | 
| 671 | 
            +
            				# and
         | 
| 672 | 
            +
            				E().diff.should == [[:foo], []] 
         | 
| 673 | 
            +
            				 
         | 
| 605 674 | 
             
            				# being that
         | 
| 675 | 
            +
            				E().diff.should eq( E().diff(E().progenitor) )
         | 
| 606 676 | 
             
            				E().progenitor.should equal(E().spec)
         | 
| 607 677 |  | 
| 608 678 | 
             
            			end
         | 
| 679 | 
            +
            			
         | 
| 680 | 
            +
            			it 'works with more methods' do
         | 
| 681 | 
            +
            			
         | 
| 682 | 
            +
            				# a tag to compare
         | 
| 683 | 
            +
            				##################################
         | 
| 684 | 
            +
            				ETag4 = E()
         | 
| 685 | 
            +
             | 
| 686 | 
            +
             | 
| 687 | 
            +
            				# ** definition **
         | 
| 688 | 
            +
            				E do
         | 
| 689 | 
            +
            					def foo 									
         | 
| 690 | 
            +
            					end
         | 
| 691 | 
            +
            					def bar
         | 
| 692 | 
            +
            					end
         | 
| 693 | 
            +
            				end
         | 
| 694 | 
            +
            				# ** definition **
         | 
| 695 | 
            +
             | 
| 696 | 
            +
             | 
| 697 | 
            +
            				#
         | 
| 698 | 
            +
            				##################################
         | 
| 699 | 
            +
            				E().diff(ETag4).join.should == []
         | 
| 700 | 
            +
            				E().diff(ETag4).delta.should == [:foo, :bar]
         | 
| 701 | 
            +
            				E().diff.join.should == [:foo, :bar]
         | 
| 702 | 
            +
            				E().diff.delta.should == []
         | 
| 703 | 
            +
            				
         | 
| 704 | 
            +
            				# being that
         | 
| 705 | 
            +
            				E().diff.should eq( E().diff( E().progenitor) )
         | 
| 706 | 
            +
            				E().progenitor.should equal( E().spec )
         | 
| 707 | 
            +
            				
         | 
| 708 | 
            +
            			end
         | 
| 709 | 
            +
            			
         | 
| 710 | 
            +
            			it 'creates injectors for inclusion' do
         | 
| 711 | 
            +
            				
         | 
| 712 | 
            +
            				# a tag to compare
         | 
| 713 | 
            +
            				##################################
         | 
| 714 | 
            +
            				ETag5 = E()
         | 
| 715 | 
            +
             | 
| 716 | 
            +
             | 
| 717 | 
            +
            				# ** definition **
         | 
| 718 | 
            +
            				E do
         | 
| 719 | 
            +
            					def foo 									
         | 
| 720 | 
            +
            					end
         | 
| 721 | 
            +
            					def bar
         | 
| 722 | 
            +
            					end
         | 
| 723 | 
            +
            				end
         | 
| 724 | 
            +
            				# ** definition **
         | 
| 725 | 
            +
             | 
| 726 | 
            +
             | 
| 727 | 
            +
            				E().diff.should be_empty
         | 
| 728 | 
            +
            				E().diff.join.should_not be_empty
         | 
| 729 | 
            +
            				E().diff.delta.should be_empty
         | 
| 730 | 
            +
            				E().diff.delta.injector.should_not eq(E().diff.join.injector)
         | 
| 731 | 
            +
            				
         | 
| 732 | 
            +
            			end
         | 
| 733 | 
            +
            			
         | 
| 609 734 | 
             
            		end
         | 
| 610 735 |  | 
| 611 736 | 
             
            	end
         |