diff --git a/docs/language/control-flow.md b/docs/language/control-flow.md index 126257e647..f61d40c71b 100644 --- a/docs/language/control-flow.md +++ b/docs/language/control-flow.md @@ -218,6 +218,36 @@ To prevent developers from writing switch statements that assume this behaviour, blocks must have at least one statement. Empty blocks are invalid. +```cadence +fun words(_ n: Int): [String] { + // Declare a variable named `result`, an array of strings, + // which stores the result + let result: [String] = [] + + // Test the value of the parameter `n` + switch n { + case 1: + // If the value of variable `n` is equal to `1`, + // then append the string "one" to the result array + result.append("one") + case 2: + // If the value of variable `n` is equal to `2`, + // then append the string "two" to the result array + result.append("two") + default: + // If the value of variable `n` is neither equal to `1` nor to `2`, + // then append the string "other" to the result array + result.append("other") + } + return result +} + +words(1) // returns `["one"]` +words(2) // returns `["two"]` +words(3) // returns `["other"]` +words(4) // returns `["other"]` +``` + ## Looping ### while-statement diff --git a/runtime/tests/interpreter/switch_test.go b/runtime/tests/interpreter/switch_test.go index 09f2a6f594..71da654a65 100644 --- a/runtime/tests/interpreter/switch_test.go +++ b/runtime/tests/interpreter/switch_test.go @@ -66,7 +66,7 @@ func TestInterpretSwitchStatement(t *testing.T) { actual, err := inter.Invoke("test", argument) require.NoError(t, err) - assert.Equal(t, actual, expected) + assert.Equal(t, expected, actual) } }) @@ -105,7 +105,7 @@ func TestInterpretSwitchStatement(t *testing.T) { actual, err := inter.Invoke("test", argument) require.NoError(t, err) - assert.Equal(t, actual, expected) + assert.Equal(t, expected, actual) } }) @@ -145,7 +145,46 @@ func TestInterpretSwitchStatement(t *testing.T) { actual, err := inter.Invoke("test", argument) require.NoError(t, err) - assert.Equal(t, actual, expected) + assert.Equal(t, expected, actual) + } + }) + + t.Run("no-implicit fallthrough", func(t *testing.T) { + + inter := parseCheckAndInterpret(t, ` + fun test(_ x: Int): [String] { + let results: [String] = [] + switch x { + case 1: + results.append("1") + case 2: + results.append("2") + default: + results.append("3") + } + return results + } + `) + + for argument, expected := range map[interpreter.Value]interpreter.Value{ + interpreter.NewIntValueFromInt64(1): interpreter.NewArrayValueUnownedNonCopying( + interpreter.NewStringValue("1"), + ), + interpreter.NewIntValueFromInt64(2): interpreter.NewArrayValueUnownedNonCopying( + interpreter.NewStringValue("2"), + ), + interpreter.NewIntValueFromInt64(3): interpreter.NewArrayValueUnownedNonCopying( + interpreter.NewStringValue("3"), + ), + interpreter.NewIntValueFromInt64(4): interpreter.NewArrayValueUnownedNonCopying( + interpreter.NewStringValue("3"), + ), + } { + + actual, err := inter.Invoke("test", argument) + require.NoError(t, err) + + assert.Equal(t, expected, actual) } }) }