Skip to content

Commit

Permalink
Add basic examples to the appengine repl (#848)
Browse files Browse the repository at this point in the history
* Add basic examples to the repl.

- Add examples covering basic CEL features and extensions
- Add evaluate button to repl console
- Fix import rewrite issue in cel/env_test for copybara
  • Loading branch information
jnthntatum authored Oct 26, 2023
1 parent d52f357 commit 46f0f09
Show file tree
Hide file tree
Showing 19 changed files with 389 additions and 56 deletions.
2 changes: 1 addition & 1 deletion cel/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
"github.com/google/cel-go/common/operators"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/test/proto3pb"

proto3pb "github.com/google/cel-go/test/proto3pb"
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)

Expand Down
29 changes: 17 additions & 12 deletions repl/appengine/web/src/app/app-component.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,23 @@
</a>
</div>

<mat-drawer-container role="main" class="content" autosize>
<!-- must be immediate childe of side-nav-container -->
<mat-drawer class="reference-panel-container" #drawer opened mode="side" position="end">
<app-reference-panel></app-reference-panel>
</mat-drawer>
<mat-drawer-content class="main-panel-container">
<div class="repl-console-container">
<app-repl-console></app-repl-console>
<mat-sidenav-container role="main" class="content" autosize>
<!-- must be immediate child of side-nav-container -->
<mat-sidenav #sidenav opened mode="side" position="end">
<div class="reference-panel-container">
<app-reference-panel></app-reference-panel>
</div>
<div class="control-button-bar">
<button mat-raised-button (click)="drawer.toggle()" color="primary">Show / Hide References</button>
</mat-sidenav>
<mat-sidenav-content>
<div class="main-panel-container">
<div class="repl-console-container">
<app-repl-console></app-repl-console>
</div>
<div class="control-button-bar">
<button mat-raised-button (click)="submitConsole()" color="primary">Evaluate</button> &nbsp;
<button mat-raised-button (click)="sidenav.toggle()" color="primary">Show / Hide References</button>
</div>
</div>
</mat-drawer-content>
</mat-drawer-container>
</mat-sidenav-content>
</mat-sidenav-container>

11 changes: 6 additions & 5 deletions repl/appengine/web/src/app/app-component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@
flex: 1;
}

$toolbar_height: 60px;

.toolbar {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 60px;
height: $toolbar_height;
display: flex;
align-items: center;
background-color: #1976d2;
Expand Down Expand Up @@ -75,14 +77,13 @@
}

.content {
display:block;
margin-top: 60px;
width: 100%;
position: absolute;
inset: $toolbar_height 0 0 0;
}

.reference-panel-container {
padding: 2rem;
max-width: 35%
max-width: 35vw;
}

.main-panel-container {
Expand Down
9 changes: 8 additions & 1 deletion repl/appengine/web/src/app/app-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
* limitations under the License.
*/

import { Component } from '@angular/core';
import { Component, ViewChild } from '@angular/core';
import { ReplConsoleComponent } from './repl_console/repl-console-component';


/**
Expand All @@ -26,4 +27,10 @@ import { Component } from '@angular/core';
styleUrls: ['./app-component.scss']
})
export class AppComponent {
@ViewChild(ReplConsoleComponent)
private console!: ReplConsoleComponent;

submitConsole() {
this.console.submit();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,46 @@

<h1>References</h1>

<p>See <a href="https://github.com/google/cel-spec">github.com/google/cel-spec</a> for CEL language
overview. </p>
<p>See
<a href="https://github.com/google/cel-go/tree/master/repl/main">github.com/google/cel-go/tree/master/repl/main</a>
for REPL syntax guide.</p>
<mat-accordion multi>
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
CEL Specification
</mat-panel-title>
</mat-expansion-panel-header>
<p>See <a href="https://github.com/google/cel-spec">github.com/google/cel-spec</a> for CEL language
overview.</p>
</mat-expansion-panel>
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
REPL Syntax
</mat-panel-title>
</mat-expansion-panel-header>
<p>See <a href="https://github.com/google/cel-go/tree/master/repl/main">github.com/google/cel-go/tree/master/repl/main</a>
for REPL syntax guide.</p>
</mat-expansion-panel >
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
Examples
</mat-panel-title>
</mat-expansion-panel-header>
<p>Standard features</p>
<mat-action-list>
<button mat-list-item (click)="startExample('hello-world')">Hello World!</button>
<button mat-list-item (click)="startExample('variables')">Variables</button>
<button mat-list-item (click)="startExample('errors')">Errors</button>
<button mat-list-item (click)="startExample('extension-functions')">Extension Functions</button>
<button mat-list-item (click)="startExample('json')">JSON</button>
<button mat-list-item (click)="startExample('macros')">Macros</button>
</mat-action-list>
<p>Canonical Extensions</p>
<mat-action-list>
<button mat-list-item (click)="startExample('optionals')">Optionals</button>
<button mat-list-item (click)="startExample('strings')">Strings</button>
<button mat-list-item (click)="startExample('math')">Math</button>
<button mat-list-item (click)="startExample('bind')">Bind</button>
</mat-action-list>
</mat-expansion-panel>
</mat-accordion>
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
*/

import { ComponentFixture, TestBed } from '@angular/core/testing';

import { MatButtonModule } from '@angular/material/button';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatListModule } from '@angular/material/list';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ReferencePanelComponent } from './reference-panel-component';

describe('ReferencePanelComponent', () => {
Expand All @@ -24,7 +28,11 @@ describe('ReferencePanelComponent', () => {

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ReferencePanelComponent ]
declarations: [ ReferencePanelComponent ],
imports: [
MatButtonModule, MatExpansionModule, MatListModule, MatFormFieldModule,
NoopAnimationsModule
]
})
.compileComponents();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,136 @@
*/

import { Component } from '@angular/core';
import { ReplExampleService, Example } from '../shared/repl-example-service';

const examples = new Map<string, Example>([
["hello-world",
{
"request": {
commands: [
`"hello world!"`
]
}
}],
["variables", {
"request": {
commands: [
`%let x = 10`,
`x + 2`,
]
}
}],
["errors", {
"request": {
commands: [
`%let x = 0`,
`false || 10 / x > 5`,
`true || 10 / x > 5`,
`10 / x > 5 || false`,
`10 / x > 5 || true`,
]
}
}],
["extension-functions", {
"request": {
commands: [
`%let string.prepend(prefix: string) : string -> prefix + this`,
`"def".prepend("abc")`,
`%let exp(base: double, exponent: int) : double ->
{-2: 1.0 / base / base,
-1: 1.0 / base,
0: 1.0,
1: base,
2: base * base
}[exponent]`,
`exp(2.0, -2) == 0.25`,
]
}
}],
["json", {
"request": {
commands: [
`%let now = timestamp("2001-01-01T00:00:01Z")`,
`%let sa_user = "example-service"`,
`{'aud': 'my-project',
'exp': now + duration('300s'),
'extra_claims': {
'group': 'admin'
},
'iat': now,
'iss': 'auth.acme.com:12350',
'nbf': now,
'sub': 'serviceAccount:' + sa_user + '@acme.com'
}`
]
}
}],
["macros", {
"request": {
commands: [
`[1, 2, 3, 4].exists(x, x > 3)`,
`[1, 2, 3, 4].all(x, x < 4)`,
`[1, 2, 3, 4].exists_one(x, x % 2 == 0)`,
`[1, 2, 3, 4].filter(x, x % 2 == 0)`,
`[1, 2, 3, 4].map(x, x * x)`,
`{'abc': 1, 'def': 2}.exists(key, key == 'def')`,
]
}
}],
["optionals",
{
request: {
commands: [
`%option --extension "optional"`,
`%let x = optional.of("one")`,
`%let y = optional.ofNonZeroValue("") // to infer optional(string)`,
`{?1: x, ?2: y} // optional construction`,
`optional.none().orValue(true)`,
`optional.of(2).optMap(x, x * 2).orValue(1)`,
`{}[?'key'].orValue(10)`,
`%let values = {1: 2, 2: 4, 3: 6}`,
`optional.ofNonZeroValue(1).optFlatMap(x, values[?x]).value()`,
`optional.none().hasValue()`
]
}
}],
[
"strings",
{
request: {
commands: [
`%option --extension "strings"`,
`"%s_%s_0x0%x".format([false, 5.0e20, 15])`,
`["a", "b", "c"].join("-")`,
`"123".reverse()`,
`" abc ".trim()`,
]
}
}],
[
"math",
{
request: {
commands: [
`%option --extension "math"`,
`math.least(-42, 40, 20)`,
`math.least(-42, 40u, -20e2)`,
`math.greatest([1, 2, 3, 4, 5])`,
]
}
}],
[
"bind",
{
request: {
commands: [
`%option --extension "bindings"`,
`cel.bind(x, 20, x * x)`,
`cel.bind(allow, [1, 2, 3, 4], [3, 2, 1, 1, 4].all(x, x in allow))`
]
}
}]
]);

/**
* Reference panel for REPL.
Expand All @@ -26,5 +156,14 @@ import { Component } from '@angular/core';
styleUrls: ['./reference-panel-component.scss']
})
export class ReferencePanelComponent {
constructor(private readonly exampleService: ReplExampleService){}

startExample(id: string) {
const example = examples.get(id);
if (example) {
this.exampleService.postExample(example);
} else {
console.error("unknown example id: ", id);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,21 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReferencePanelComponent } from './reference-panel-component';


import { MatButtonModule } from '@angular/material/button';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatListModule } from '@angular/material/list';

@NgModule({
declarations: [
ReferencePanelComponent
],
imports: [
CommonModule
CommonModule,
MatButtonModule,
MatExpansionModule,
MatFormFieldModule,
MatListModule,
],
exports: [
ReferencePanelComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,18 @@ <h1>REPL Console</h1>

<div class="repl-input-block" (keydown)="onEnter($event)">
<!-- Inputs for previously entered REPL commands -->
<div class="statement-block" *ngFor="let response of lastEvaluate.responses; let i = index">
<div class="statement-block" *ngFor="let command of lastRequest.commands; let i = index">
<mat-form-field class="statement-container" appearance="outline">
<mat-label>{{i + 1}}</mat-label>

<input matInput class="repl-stmt-input"
value="{{lastRequest.commands[i]}}"
value="{{command}}"
[attr.data-stmt-index]="i"
(keydown.ArrowUp)="handleUp(i)"
(keydown.ArrowDown)="handleDown(i)">

<mat-hint>
<code class="repl-out-ok">{{response.replOutput || (response.issue? '&lt;err&gt;' : '&lt;ok&gt;' ) | trim:80}}</code>
<code *ngIf="getResponse(i).evaluated" class="repl-out-ok">{{getResponse(i).replOutput || (getResponse(i).issue ? '&lt;err&gt;' : '&lt;ok&gt;' ) | trim:80}}</code>
</mat-hint>

</mat-form-field>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@
.reset-wrapper {
position: absolute;
right: 2rem;
top: 6rem;
top: 4rem;
}
Loading

0 comments on commit 46f0f09

Please sign in to comment.