[squeak-dev] The Inbox: MorphicTests-tobe.53.mcz

commits at source.squeak.org commits at source.squeak.org
Thu Sep 19 14:55:02 UTC 2019


A new version of MorphicTests was added to project The Inbox:
http://source.squeak.org/inbox/MorphicTests-tobe.53.mcz

==================== Summary ====================

Name: MorphicTests-tobe.53
Author: tobe
Time: 19 September 2019, 4:55:02.076838 pm
UUID: 66353635-22e9-4481-8de8-fd8f470e8aea
Ancestors: MorphicTests-mt.52

Some tests for the TableLayout, ScrollPane and Morph layouting. It includes examples for table layouts that may act as a reference for users.

Please do check if you agree with the way the morph hierarchies are built-up, if we want this code to act as a form of reference as well.

=============== Diff against MorphicTests-mt.52 ===============

Item was added:
+ TestCase subclass: #MorphLayoutTest
+ 	instanceVariableNames: ''
+ 	classVariableNames: ''
+ 	poolDictionaries: ''
+ 	category: 'MorphicTests-Layouts'!

Item was added:
+ ----- Method: MorphLayoutTest>>ensureLayout: (in category 'helper') -----
+ ensureLayout: aMorph
+ 
+ 	^ aMorph
+ 		fullBounds;
+ 		yourself!

Item was added:
+ ----- Method: MorphLayoutTest>>testAdhereToEdge (in category 'tests') -----
+ testAdhereToEdge
+ 
+ 	| child container |
+ 	container := Morph new
+ 		extent: 300 @ 200;
+ 		addMorphBack: (child := Morph new extent: 100 @ 100).
+ 	
+ 	child adhereToEdge: #right.
+ 	self ensureLayout: container.
+ 	self assert: 200 @ 0 equals: child position.
+ 	
+ 	child adhereToEdge: #bottom.
+ 	self ensureLayout: container.
+ 	self assert: 200 @ 100 equals: child position.
+ 	
+ 	child adhereToEdge: #topLeft.
+ 	self ensureLayout: container.
+ 	self assert: 0 @ 0 equals: child position!

Item was added:
+ ----- Method: MorphLayoutTest>>testLayoutPropertyAssertions (in category 'tests') -----
+ testLayoutPropertyAssertions
+ 
+ 	| morph |
+ 	morph := Morph new.
+ 	
+ 	self should: [morph vResizing: #shrriinkWraap] raise: Error.
+ 	self should: [morph hResizing: #spaceFlll] raise: Error.
+ 	self should: [morph cellSpacing: 0] raise: Error.
+ 	self should: [morph cellSpacing: #glob] raise: Error.
+ 	self should: [morph listSpacing: 2] raise: Error.
+ 	self should: [morph listSpacing: #eq] raise: Error!

Item was added:
+ ----- Method: MorphLayoutTest>>testManualPositions (in category 'tests') -----
+ testManualPositions
+ 
+ 	| container greenMorph redMorph |
+ 	container := Morph new
+ 		addMorphBack: (redMorph := Morph new color: Color red; extent: 30 @ 20; position: 20 @ 20);
+ 		addMorphBack: (greenMorph := Morph new color: Color green;  extent: 200 @ 300; position: 80 @ 80).
+ 	
+ 	self ensureLayout: container.
+ 	self assert: Morph new extent equals: container extent.
+ 	
+ 	container extent: 300 @ 300.
+ 	self assert: 300 @ 300 equals: container extent!

Item was added:
+ ----- Method: MorphLayoutTest>>testScrollPaneBarUpdate (in category 'tests') -----
+ testScrollPaneBarUpdate
+ 
+ 	| child container |
+ 	container := ScrollPane new color: Color green; extent: 300 @ 300; showVScrollBarOnlyWhenNeeded; showHScrollBarOnlyWhenNeeded.
+ 	container scroller addMorphBack: (child := Morph new color: Color red; extent: 100 @ 100).
+ 	
+ 	self ensureLayout: container.
+ 	self assert: container hScrollBar owner isNil.
+ 	self assert: container vScrollBar owner isNil.
+ 	
+ 	child extent: 400 @ 100.
+ 	self ensureLayout: container.
+ 	self assert: container hScrollBar owner notNil.
+ 	self assert: container vScrollBar owner isNil.
+ 	
+ 	child extent: 400 @ 400.
+ 	self ensureLayout: container.
+ 	self assert: container hScrollBar owner notNil.
+ 	self assert: container hScrollBar owner notNil!

Item was added:
+ TestCase subclass: #TableLayoutTest
+ 	instanceVariableNames: ''
+ 	classVariableNames: ''
+ 	poolDictionaries: ''
+ 	category: 'MorphicTests-Layouts'!

Item was added:
+ ----- Method: TableLayoutTest>>defaultFont (in category 'helper') -----
+ defaultFont
+ 
+ 	^ TextStyle defaultFont!

Item was added:
+ ----- Method: TableLayoutTest>>defaultMorphSize (in category 'helper') -----
+ defaultMorphSize
+ 
+ 	^ Morph new extent!

Item was added:
+ ----- Method: TableLayoutTest>>ensureLayout: (in category 'helper') -----
+ ensureLayout: aMorph
+ 
+ 	^ aMorph
+ 		fullBounds;
+ 		yourself!

Item was added:
+ ----- Method: TableLayoutTest>>expectedFailures (in category 'failures') -----
+ expectedFailures
+ 
+ 	^ #(testDialog)!

Item was added:
+ ----- Method: TableLayoutTest>>newContainer (in category 'helper') -----
+ newContainer
+ 
+ 	^ Morph new
+ 		layoutPolicy: TableLayout new;
+ 		vResizing: #shrinkWrap;
+ 		hResizing: #shrinkWrap;
+ 		listDirection: #leftToRight;
+ 		color: self randomColor!

Item was added:
+ ----- Method: TableLayoutTest>>newMorph (in category 'helper') -----
+ newMorph
+ 
+ 	^ Morph new
+ 		layoutPolicy: TableLayout new;
+ 		color: self randomColor!

Item was added:
+ ----- Method: TableLayoutTest>>randomColor (in category 'helper') -----
+ randomColor
+ 
+ 	^ Color h: 360 atRandom s: 1 v: 1!

Item was added:
+ ----- Method: TableLayoutTest>>repeat:times: (in category 'helper') -----
+ repeat: aNumber times: aString
+ 
+ 	^ String streamContents: [:stream |
+ 		aNumber timesRepeat: [stream nextPutAll: aString]]!

Item was added:
+ ----- Method: TableLayoutTest>>testBrowser (in category 'tests - example layouts') -----
+ testBrowser
+ 	" replicate the layout used by the system browser with a table layout "
+ 
+ 	| container buttons |
+ 	buttons := #('browse' 'senders' 'implementors' 'versions' 'inheritance' 'hierarchy' 'vars' 'source') collect: [:label |
+ 		self newMorph
+ 			hResizing: #spaceFill;
+ 			vResizing: #shrinkWrap;
+ 			wrapCentering: #center;
+ 			layoutPolicy: TableLayout new;
+ 			layoutInset: 8;
+ 			addMorph: (StringMorph new contents: label)].
+ 	
+ 	container := self newContainer
+ 		listDirection: #topToBottom;
+ 		layoutInset: 8;
+ 		cellGap: 8;
+ 		addMorphBack: (self newContainer
+ 			cellGap: 8;
+ 			listDirection: #leftToRight;
+ 			hResizing: #spaceFill;
+ 			vResizing: #spaceFill;
+ 			minimumHeight: 30;
+ 			addMorphBack: (self newMorph hResizing: #spaceFill; vResizing: #spaceFill);
+ 			addMorphBack: (self newMorph hResizing: #spaceFill; vResizing: #spaceFill);
+ 			addMorphBack: (self newMorph hResizing: #spaceFill; vResizing: #spaceFill);
+ 			addMorphBack: (self newMorph hResizing: #spaceFill; vResizing: #spaceFill));
+ 		addMorphBack: (self newContainer
+ 			vResizing: #shrinkWrap;
+ 			hResizing: #spaceFill;
+ 			cellGap: 2;
+ 			addAllMorphsBack: buttons);
+ 		addMorphBack: (self newMorph
+ 			minimumHeight: 100;
+ 			hResizing: #spaceFill;
+ 			vResizing: #spaceFill).
+ 	
+ 	container extent: 0 @ 0.
+ 	"container openInHand."
+ 	
+ 	self ensureLayout: container.
+ 	self assert: 100 + 30 + self defaultFont height + (8 * 6) equals: container height!

Item was added:
+ ----- Method: TableLayoutTest>>testCellGap (in category 'tests') -----
+ testCellGap
+ 
+ 	| container first gap second |
+ 	gap := 13.
+ 	container := self newContainer
+ 		cellGap: gap;
+ 		addMorphBack: (first := self newMorph);
+ 		addMorphBack: (second := self newMorph).
+ 	
+ 	container listDirection: #leftToRight.
+ 	self ensureLayout: container.
+ 	self assert: (self defaultMorphSize x * 2 + gap) @ self defaultMorphSize y equals: container extent.
+ 	self assert: (0 @ 0 extent: first extent) equals: first bounds.
+ 	self assert: (first width + gap @ 0 extent: second extent) equals: second bounds.
+ 	
+ 	container listDirection: #topToBottom.
+ 	self ensureLayout: container.
+ 	self assert: self defaultMorphSize x @ (self defaultMorphSize y * 2 + gap) equals: container extent.
+ 	self assert: (0 @ 0 extent: first extent) equals: first bounds.
+ 	self assert: (0 @ (first height + gap) extent: second extent) equals: second bounds.
+ 	
+ 	container listDirection: #rightToLeft.
+ 	self ensureLayout: container.
+ 	" changing listDirection here moves our container in the world, reset for easier assertions "
+ 	container position: 0 @ 0.
+ 	
+ 	self assert: (self defaultMorphSize x * 2 + gap) @ self defaultMorphSize y equals: container extent.
+ 	self assert: (0 @ 0 extent: second extent) equals: second bounds.
+ 	self assert: (second width + gap @ 0 extent: first extent) equals: first bounds.
+ 	
+ 	container listDirection: #bottomToTop.
+ 	self ensureLayout: container.
+ 	container position: 0 @ 0.
+ 	self assert: self defaultMorphSize x @ (self defaultMorphSize y * 2 + gap) equals: container extent.
+ 	self assert: (0 @ 0 extent: second extent) equals: second bounds.
+ 	self assert: (0 @ (second height + gap) extent: first extent) equals: first bounds!

Item was added:
+ ----- Method: TableLayoutTest>>testCellInset (in category 'tests') -----
+ testCellInset
+ 
+ 	| container first second inset |
+ 	container := self newContainer
+ 		addMorphBack: (first := self newMorph);
+ 		addMorphBack: (second := self newMorph).
+ 	
+ 	inset := 13.
+ 	self ensureLayout: (container cellInset: inset).
+ 	self assert: (self defaultMorphSize x  * 2 + (inset * 4)) @ (self defaultMorphSize y + (inset * 2)) equals: container extent.
+ 	
+ 	inset := Rectangle left: 13 right: 7 top: 3 bottom: 17.
+ 	self ensureLayout: (container cellInset: inset).
+ 	self assert: (self defaultMorphSize x * 2 + (inset left + inset right * 2)) @ (self defaultMorphSize y + (inset top + inset right * 2)) equals: container extent.
+ 	
+ 	inset := 7 @ 13.
+ 	self ensureLayout: (container cellInset: inset).
+ 	self assert: (self defaultMorphSize x * 2) + (inset x * 2 * 2) @ (self defaultMorphSize y + (inset y * 2)) equals: container extent!

Item was added:
+ ----- Method: TableLayoutTest>>testDialog (in category 'tests - example layouts') -----
+ testDialog
+ 	" construct a typical yes/no confirm dialog.
+ 	
+ 	the test itself is currently expected to fail, as we do not support minimum extent that is derived from layout for rigid containers "
+ 
+ 	| container contentLabel font spacing |
+ 	spacing := 8.
+ 	container := self newContainer
+ 		listDirection: #topToBottom;
+ 		hResizing: #rigid;
+ 		cellGap: spacing;
+ 		layoutInset: (Rectangle left: 0 right: 0 top: 0 bottom: spacing);
+ 		addMorphBack: (self newContainer
+ 			cellGap: spacing;
+ 			hResizing: #spaceFill;
+ 			layoutInset: spacing;
+ 			addMorphBack: (self newMorph extent: 16 asPoint);
+ 			addMorphBack: (TextMorph new contents: 'Please Confirm'; hResizing: #spaceFill; centered);
+ 			addMorphBack: (self newMorph extent: 16 asPoint));
+ 		addMorphBack: (contentLabel := TextMorph new margins: spacing @ 0; vResizing: #shrinkWrap; hResizing: #spaceFill);
+ 		addMorphBack: (self newContainer
+ 			cellGap: spacing;
+ 			addMorphBack: (self newMorph extent: 50 @ 26);
+ 			addMorphBack: (self newMorph extent: 50 @ 26)).
+ 	"container openInHand."
+ 	
+ 	font := self defaultFont.
+ 	contentLabel contents: (self repeat: 80 times: 'a ').
+ 	
+ 	container width: (font widthOfString: contentLabel contents) + 2 + (spacing * 2).
+ 	self ensureLayout: container.
+ 	self assert: (font widthOfString: contentLabel contents) + 2 + (spacing * 2) equals: container width.
+ 	
+ 	container width: (font widthOfString: contentLabel contents) // 2.
+ 	self ensureLayout: container.
+ 	self assert: ((font widthOfString: contentLabel contents) // 2) equals: container width.
+ 	
+ 	" ensure we can't resize below our children's width "
+ 	container width: 0.
+ 	self ensureLayout: container.
+ 	self assert: container firstSubmorph width equals: container width!

Item was added:
+ ----- Method: TableLayoutTest>>testListCentering (in category 'tests') -----
+ testListCentering
+ 
+ 	| container firstChild secondChild thirdChild |
+ 	container := self newContainer
+ 		hResizing: #rigid;
+ 		vResizing: #rigid;
+ 		listDirection: #topToBottom;
+ 		wrapCentering: #topLeft;
+ 		extent: 100 @ 200;
+ 		addMorphBack: (firstChild := self newMorph extent: 50 @ 50);
+ 		addMorphBack: (secondChild := self newMorph extent: 80 @ 50);
+ 		addMorphBack: (thirdChild := self newMorph extent: 50 @ 50).
+ 	
+ 	container listCentering: #topLeft.
+ 	self ensureLayout: container.
+ 	" 15 is (80 - 50) / 2, because of the wrapCentering we fill to the large child and then center "
+ 	self assert: 15 @ 0 equals: firstChild position.
+ 	self assert: 0 @ 50 equals: secondChild position.
+ 	self assert: 15 @ 100 equals: thirdChild position.
+ 	
+ 	container listCentering: #bottomRight.
+ 	self ensureLayout: container.
+ 	self assert: 15 @ 50 equals: firstChild position.
+ 	self assert: 0 @ 100 equals: secondChild position.
+ 	self assert: 15 @ 150 equals: thirdChild position.
+ 	
+ 	container listCentering: #justified.
+ 	self ensureLayout: container.
+ 	self assert: 15 @ 0 equals: firstChild position.
+ 	" center of the parent morph: "
+ 	self assert: 0 @ ((200 / 2) - (50 / 2)) equals: secondChild position.
+ 	self assert: 15 @ 150 equals: thirdChild position.
+ 	
+ 	container listCentering: #center.
+ 	self ensureLayout: container.
+ 	self assert: 15 @ 25 equals: firstChild position.
+ 	self assert: 0 @ ((200 / 2) - (50 / 2)) equals: secondChild position.
+ 	self assert: 15 @ 125 equals: thirdChild position!

Item was added:
+ ----- Method: TableLayoutTest>>testScrollPaneShrinkWrap (in category 'tests') -----
+ testScrollPaneShrinkWrap
+ 
+ 	| container scroll scrollContent |
+ 	container := self newContainer
+ 		vResizing: #rigid;
+ 		addMorphBack: (self newMorph extent: 50 @ 50);
+ 		addMorphBack: (scroll := ScrollPane new
+ 			hResizing: #shrinkWrap;
+ 			vResizing: #spaceFill;
+ 			showVScrollBarOnlyWhenNeeded;
+ 			hideHScrollBarIndefinitely).
+ 	
+ 	" shrinkWrap the horizontal axis but scroll vertically "
+ 	scroll scroller
+ 		layoutPolicy: TableLayout new;
+ 		addMorphBack: (scrollContent := self newMorph extent: 200 @ 500).
+ 	
+ 	container extent: 250 @ 300.
+ 	self ensureLayout: container.
+ 	self assert: 211 @ 300 equals: scroll extent.
+ 	
+ 	scrollContent extent: 300 @ 500.
+ 	self ensureLayout: container.
+ 	self assert: 311 @ 300 equals: scroll extent!

Item was added:
+ ----- Method: TableLayoutTest>>testShrinkWrapAndSpaceFill (in category 'tests') -----
+ testShrinkWrapAndSpaceFill
+ 
+ 	| container shrinkWrapped spaceFilled |
+ 	container := self newContainer
+ 		addMorphBack: (spaceFilled := self newMorph hResizing: #spaceFill; vResizing: #spaceFill);
+ 		addMorphBack: (shrinkWrapped := self newMorph hResizing: #shrinkWrap; vResizing: #shrinkWrap).
+ 	
+ 	" minimal size "
+ 	self ensureLayout: container.
+ 	self assert: 1 equals: spaceFilled width.
+ 	self assert: self defaultMorphSize equals: shrinkWrapped extent.
+ 	
+ 	" scale up horizontally "
+ 	self ensureLayout: (container extent: self defaultMorphSize x * 2 @ self defaultMorphSize y).
+ 	self assert: self defaultMorphSize equals: spaceFilled extent.
+ 	self assert: self defaultMorphSize equals: shrinkWrapped extent.
+ 	
+ 	" scale up in horizontally and vertically "
+ 	self ensureLayout: (container extent: self defaultMorphSize * 2).
+ 	self assert: self defaultMorphSize x @ (self defaultMorphSize y * 2) equals: spaceFilled extent.
+ 	self assert: self defaultMorphSize equals: shrinkWrapped extent!

Item was added:
+ ----- Method: TableLayoutTest>>testShrinkWrapScrollPaneAlwaysShowBars (in category 'tests') -----
+ testShrinkWrapScrollPaneAlwaysShowBars
+ 
+ 	| container scroll scrollContent |
+ 	container := self newContainer
+ 		vResizing: #shrinkWrap;
+ 		hResizing: #shrinkWrap;
+ 		addMorphBack: (scroll := ScrollPane new
+ 			hResizing: #shrinkWrap;
+ 			vResizing: #shrinkWrap;
+ 			alwaysShowHScrollBar;
+ 			alwaysShowVScrollBar).
+ 	
+ 	scroll scroller
+ 		layoutPolicy: TableLayout new;
+ 		addMorphBack: (scrollContent := self newMorph extent: 300 @ 300).
+ 	
+ 	self ensureLayout: container.
+ 	self assert: (300 @ 300) + scroll scrollBarThickness + scroll borderWidth equals: container extent!

Item was added:
+ ----- Method: TableLayoutTest>>testSidebarAndScrollingView (in category 'tests - example layouts') -----
+ testSidebarAndScrollingView
+ 	" construct a container that has a fixed size sidebar on the left and a scrolling window that adapts flexibly to the container's size "
+ 
+ 	| container scrolling sidebar content title |
+ 	container := self newContainer
+ 		addMorphBack: (sidebar := self newMorph width: 200; hResizing: #rigid; vResizing: #spaceFill);
+ 		addMorphBack: (scrolling := ScrollPane new hResizing: #spaceFill; vResizing: #spaceFill).
+ 	
+ 	scrolling scroller
+ 		layoutPolicy: TableLayout new;
+ 		addMorphBack: (self newContainer
+ 			hResizing: #spaceFill;
+ 			vResizing: #spaceFill;
+ 			listDirection: #topToBottom;
+ 			addMorphBack: (title := TextMorph new hResizing: #spaceFill; contents: 'Here comes a title');
+ 			addMorphBack: (content := self newMorph extent: 400 @ 400; hResizing: #spaceFill)).
+ 	"container openInHand."
+ 	
+ 	container extent: 500 @ 500.
+ 	self ensureLayout: container.
+ 	self assert: 200 @ 500 equals: sidebar extent.
+ 	self assert: 300 @ 500 equals: scrolling extent.
+ 	self assert: 300 - (scrolling borderWidth  * 2) @ 400 equals: content extent.
+ 	
+ 	container extent: 300 @ 300.
+ 	self ensureLayout: container.
+ 	self assert: 200 @ 300 equals: sidebar extent.
+ 	self assert: 100 @ 300 equals: scrolling extent.
+ 	self assert: 100 - scrolling borderWidth - scrolling scrollBarThickness @ 400 equals: content extent!

Item was added:
+ ----- Method: TableLayoutTest>>testTwoTextMorphsHorizontal (in category 'tests') -----
+ testTwoTextMorphsHorizontal
+ 
+ 	| container str1 str2 label2 label1 heightAt200 |
+ 	str1 := 'abc def'.
+ 	str2 := 'tzu ghj qwe'.
+ 	container := self newContainer
+ 		hResizing: #spaceFill;
+ 		vResizing: #shrinkWrap;
+ 		addMorphBack: (label1 := TextMorph new contents: str1; wrapFlag: true; hResizing: #spaceFill);
+ 		addMorphBack: (label2 := TextMorph new contents: str2; wrapFlag: true; hResizing: #spaceFill).
+ 	
+ 	container width: 200.
+ 	self ensureLayout: container.
+ 	heightAt200 := container height.
+ 	
+ 	self assert: 100 equals: label1 width.
+ 	self assert: 100 equals: label2 width.
+ 	
+ 	container width: 100.
+ 	self ensureLayout: container.
+ 	self assert: 50 equals: label1 width.
+ 	self assert: 50 equals: label2 width.
+ 	self assert: container height > heightAt200.
+ 	
+ 	container width: 10000.
+ 	self ensureLayout: container.
+ 	self assert: 5000 equals: label1 width.
+ 	self assert: 5000 equals: label2 width.
+ 	self assert: self defaultFont height + 2 equals: container height!

Item was added:
+ ----- Method: TableLayoutTest>>testTwoTextMorphsVertical (in category 'tests') -----
+ testTwoTextMorphsVertical
+ 
+ 	| container str1 str2 label2 label1 font |
+ 	str1 := 'abc def'.
+ 	str2 := 'tzu ghj qwe'.
+ 	container := self newContainer
+ 		hResizing: #spaceFill;
+ 		vResizing: #shrinkWrap;
+ 		listDirection: #topToBottom;
+ 		addMorphBack: (label1 := TextMorph new contents: str1; wrapFlag: true; hResizing: #spaceFill);
+ 		addMorphBack: (label2 := TextMorph new contents: str2; wrapFlag: true; hResizing: #spaceFill).
+ 	
+ 	font := self defaultFont.
+ 	
+ 	container width: 200.
+ 	self ensureLayout: container.
+ 	self assert: 200 @ (font height + 2) equals: label1 extent.
+ 	self assert: 200 @ (font height + 2) equals: label2 extent.
+ 	
+ 	container width: 50.
+ 	self ensureLayout: container.
+ 	self assert: 50 equals: label1 width.
+ 	self assert: 50 equals: label2 width.
+ 	" check that we land on a multiple of the line height "
+ 	self assert: 0 equals: container height \\ (font height + 2).
+ 	
+ 	container width: 20.
+ 	self ensureLayout: container.
+ 	self assert: 20 equals: label1 width.
+ 	self assert: 20 equals: label2 width.
+ 	" check that we land on a multiple of the line height "
+ 	self assert: 0 equals: container height \\ (font height + 2)!

Item was added:
+ ----- Method: TableLayoutTest>>testWrappingLayout (in category 'tests') -----
+ testWrappingLayout
+ 
+ 	| container |
+ 	container := self newContainer
+ 		hResizing: #rigid;
+ 		listDirection: #leftToRight;
+ 		wrapDirection: #none;
+ 		addMorphBack: (self newMorph extent: 50 @ 50);
+ 		addMorphBack: (self newMorph extent: 50 @ 50);
+ 		addMorphBack: (self newMorph extent: 50 @ 50).
+ 	
+ 	container width: 50.
+ 	self ensureLayout: container.
+ 	self assert: 50 @ 50 equals: container extent.
+ 	self assert: #(0 50 100) equals: (container submorphs collect: #left).
+ 	
+ 	container wrapDirection: #leftToRight.
+ 	self ensureLayout: container.
+ 	self assert: 50 @ 150 equals: container extent.
+ 	self assert: #(0 0 0) equals: (container submorphs collect: #left).
+ 	
+ 	container width: 125.
+ 	self ensureLayout: container.
+ 	self assert: 125 @ 100 equals: container extent.
+ 	self assert: #(0 50 0) equals: (container submorphs collect: #left)!



More information about the Squeak-dev mailing list